From patchwork Wed Aug 19 14:15:15 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Klug X-Patchwork-Id: 27848 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by patchwork.libcamera.org (Postfix) with ESMTPS id 5A0A9C3308 for ; Thu, 20 Aug 2026 10:50:13 +0000 (UTC) Received: from monstersaurus.ideasonboard.com (cpc89244-aztw30-2-0-cust6594.18-1.cable.virginm.net [86.31.185.195]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id F167F8FD for ; Thu, 20 Aug 2026 12:48:50 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1787222932; bh=8/AexbRW7ghgF6jDSWxE/dNrSlFXleg+8sfDcSg64n8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=YoohkCz4Iq+PX3XL35txthryYihRkTGg9x9vpYuGToLd5lVSE492ISXWmDrqDuPyA nRc8Vt743/O8ieHYKsEbY5ZPQHeG2JJfk0dygOOtiH9CrOBgYOmofL3nfgLIfoBc9P d9FXhy7FZc1OEbbOKjkNzvJX9BcNDIqfo5ho+a8k= Received: by monstersaurus.ideasonboard.com (sSMTP sendmail emulation); Thu, 20 Aug 2026 11:50:11 +0100 Delivered-To: kbingham@ideasonboard.com Received: from perceval.ideasonboard.com by perceval.ideasonboard.com with LMTP id uOFlBUu6hWpsaBYA4E0KoQ (envelope-from ) for ; Wed, 19 Aug 2026 16:14:35 +0200 Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by perceval.ideasonboard.com (Postfix) with ESMTPS id E21EAE4E; Wed, 19 Aug 2026 16:14:34 +0200 (CEST) Authentication-Results: perceval.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.a=rsa-sha256 header.s=mail header.b=W/vGr+Mz; dkim-atps=neutral Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id C37CA68318; Wed, 19 Aug 2026 16:15:54 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="W/vGr+Mz"; 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 30592681A1 for ; Wed, 19 Aug 2026 16:15:52 +0200 (CEST) Received: from ideasonboard.com (unknown [IPv6:2a00:6020:448c:6c00:84bc:8eb1:e39f:793f]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 64CC7BE1; Wed, 19 Aug 2026 16:14:31 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1787148871; bh=8/AexbRW7ghgF6jDSWxE/dNrSlFXleg+8sfDcSg64n8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=W/vGr+MzlEBuGW9qkNnX97iG1gJe3/5JPrDq2oq+ZND13ynRABJidMqkmrJxErPWF U1fqmf+2hRJOHchRjynauoRhCpgyo5da+fxUfqFU1aJvxAUkOnOPK3WNKoFx4ABrVT quqtoit0eRarREUZjbLRDDbE1K5YjFAQqT+Uz6lc= From: Stefan Klug To: libcamera-devel@lists.libcamera.org Cc: Stefan Klug , Naushir Patuck Subject: [PATCH v2 2/3] libcamera: ipa: core: Use native coordinates for IPACameraSensorInfo::analogCrop Date: Wed, 19 Aug 2026 16:15:15 +0200 Message-ID: <20260819141541.221617-3-stefan.klug@ideasonboard.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260819141541.221617-1-stefan.klug@ideasonboard.com> References: <20260819141541.221617-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" X-TUID: 1y23H3mj1+NR Now that the camera properties use the physical pixel array as reference coordinate system, do the same with IPACameraSensorInfo::analogCrop. Replace IPACameraSensorInfo::activeAreaSize with IPACameraSensorInfo::activeArea to be able to keep the existing calculations. Co-developed-by: Naushir Patuck Signed-off-by: Naushir Patuck Signed-off-by: Stefan Klug --- Changes in v2: - Moved all hunks related to IPACameraSensorInfo from the previous patch to this one - Fixed some missing documentation changes - Moved IPACameraSensorInfo::pixelArraySize to a separate patch - Pulled in changes by Naush - Kept the rkisp1 lsc logic. The related changes will come one top --- include/libcamera/ipa/core.mojom | 19 +++++++++++++------ src/ipa/mali-c55/algorithms/lsc.cpp | 2 +- src/ipa/rkisp1/algorithms/lsc.cpp | 2 +- src/ipa/rpi/common/ipa_base.cpp | 13 +++++++++---- src/libcamera/sensor/camera_sensor_legacy.cpp | 17 +++-------------- src/libcamera/sensor/camera_sensor_raw.cpp | 17 +++-------------- 6 files changed, 30 insertions(+), 40 deletions(-) diff --git a/include/libcamera/ipa/core.mojom b/include/libcamera/ipa/core.mojom index bce797245829..d3375333baa0 100644 --- a/include/libcamera/ipa/core.mojom +++ b/include/libcamera/ipa/core.mojom @@ -153,17 +153,24 @@ module libcamera; */ /** - * \var IPACameraSensorInfo::activeAreaSize - * \brief The size of the pixel array active area of the sensor + * \var IPACameraSensorInfo::activeArea + * \brief The active pixel area of the sensor, relative to the physical pixel + * array + * + * The active area rectangle is expressed relative to the top-left corner of the + * physical pixel array. It describes the region of the pixel array which + * produces valid image data, excluding non-readable and optical black pixels. + * + * \note New IPA implementations should *not* use this property and instead rely + * on coordinates relative to the physical sensor array */ /** * \var IPACameraSensorInfo::analogCrop - * \brief The portion of the pixel array active area which is read-out and - * processed + * \brief The portion of the pixel array which is read-out and processed * * The analog crop rectangle top-left corner is defined as the displacement - * from the top-left corner of the pixel array active area. The rectangle + * from the top-left corner of the physical pixel array. The rectangle * horizontal and vertical sizes define the portion of the pixel array which * is read-out and provided to the sensor's internal processing pipeline, before * any pixel sub-sampling method, such as pixel binning, skipping and averaging @@ -243,7 +250,7 @@ struct IPACameraSensorInfo { uint32 bitsPerPixel; uint32 cfaPattern; - Size activeAreaSize; + Rectangle activeArea; Rectangle analogCrop; Size outputSize; diff --git a/src/ipa/mali-c55/algorithms/lsc.cpp b/src/ipa/mali-c55/algorithms/lsc.cpp index fff0dc7d0e64..6cd4e9020504 100644 --- a/src/ipa/mali-c55/algorithms/lsc.cpp +++ b/src/ipa/mali-c55/algorithms/lsc.cpp @@ -57,7 +57,7 @@ int Lsc::init(IPAContext &context, const ValueNode &tuningData) .keys = { "r", "g", "b" }, .numHSamples = kMeshSize, .numVSamples = kMeshSize, - .sensorSize = context.sensorInfo.activeAreaSize + .sensorSize = context.sensorInfo.activeArea.size() }); } diff --git a/src/ipa/rkisp1/algorithms/lsc.cpp b/src/ipa/rkisp1/algorithms/lsc.cpp index f2858656023e..bb41dd3682bd 100644 --- a/src/ipa/rkisp1/algorithms/lsc.cpp +++ b/src/ipa/rkisp1/algorithms/lsc.cpp @@ -127,7 +127,7 @@ int LensShadingCorrection::init([[maybe_unused]] IPAContext &context, .keys = { "r", "gr", "gb", "b" }, .numHSamples = RKISP1_CIF_ISP_LSC_SAMPLES_MAX, .numVSamples = RKISP1_CIF_ISP_LSC_SAMPLES_MAX, - .sensorSize = context.sensorInfo.activeAreaSize + .sensorSize = context.sensorInfo.activeArea.size() }); } diff --git a/src/ipa/rpi/common/ipa_base.cpp b/src/ipa/rpi/common/ipa_base.cpp index 7e00c2799b4e..9b851007a124 100644 --- a/src/ipa/rpi/common/ipa_base.cpp +++ b/src/ipa/rpi/common/ipa_base.cpp @@ -561,10 +561,15 @@ void IpaBase::setMode(const IPACameraSensorInfo &sensorInfo) mode_.bitdepth = sensorInfo.bitsPerPixel; mode_.width = sensorInfo.outputSize.width; mode_.height = sensorInfo.outputSize.height; - mode_.sensorWidth = sensorInfo.activeAreaSize.width; - mode_.sensorHeight = sensorInfo.activeAreaSize.height; - mode_.cropX = sensorInfo.analogCrop.x; - mode_.cropY = sensorInfo.analogCrop.y; + mode_.sensorWidth = sensorInfo.activeArea.width; + mode_.sensorHeight = sensorInfo.activeArea.height; + /* + * CameraMode::cropX/Y are defined relative to the active pixel area, + * whereas IPACameraSensorInfo::analogCrop is relative to the physical + * pixel array. Rebase the crop origin onto the active area. + */ + mode_.cropX = sensorInfo.analogCrop.x - sensorInfo.activeArea.x; + mode_.cropY = sensorInfo.analogCrop.y - sensorInfo.activeArea.y; mode_.pixelRate = sensorInfo.pixelRate; /* diff --git a/src/libcamera/sensor/camera_sensor_legacy.cpp b/src/libcamera/sensor/camera_sensor_legacy.cpp index ef2bf656f845..9e32f798c2dd 100644 --- a/src/libcamera/sensor/camera_sensor_legacy.cpp +++ b/src/libcamera/sensor/camera_sensor_legacy.cpp @@ -883,11 +883,10 @@ int CameraSensorLegacy::sensorInfo(IPACameraSensorInfo *info) const info->model = model(); /* - * The active area size is a static property, while the crop - * rectangle needs to be re-read as it depends on the sensor - * configuration. + * The active area is a static property, while the crop rectangle needs + * to be re-read as it depends on the sensor configuration. */ - info->activeAreaSize = { activeArea_.width, activeArea_.height }; + info->activeArea = activeArea_; /* * \todo Support for retreiving the crop rectangle is scheduled to @@ -901,16 +900,6 @@ int CameraSensorLegacy::sensorInfo(IPACameraSensorInfo *info) const << "The analogue crop rectangle has been defaulted to the active area size"; } - /* - * IPACameraSensorInfo::analogCrop::x and IPACameraSensorInfo::analogCrop::y - * are defined relatively to the active pixel area, while V4L2's - * TGT_CROP target is defined in respect to the full pixel array. - * - * Compensate it by subtracting the active area offset. - */ - info->analogCrop.x -= activeArea_.x; - info->analogCrop.y -= activeArea_.y; - /* The bit depth and image size depend on the currently applied format. */ V4L2SubdeviceFormat format{}; ret = subdev_->getFormat(pad_, &format); diff --git a/src/libcamera/sensor/camera_sensor_raw.cpp b/src/libcamera/sensor/camera_sensor_raw.cpp index 544d0e52c20d..a1f48b5ff557 100644 --- a/src/libcamera/sensor/camera_sensor_raw.cpp +++ b/src/libcamera/sensor/camera_sensor_raw.cpp @@ -1009,27 +1009,16 @@ int CameraSensorRaw::sensorInfo(IPACameraSensorInfo *info) const info->model = model(); /* - * The active area size is a static property, while the crop - * rectangle needs to be re-read as it depends on the sensor - * configuration. + * The active area is a static property, while the crop rectangle needs + * to be re-read as it depends on the sensor configuration. */ - info->activeAreaSize = { activeArea_.width, activeArea_.height }; + info->activeArea = activeArea_; int ret = subdev_->getSelection(streams_.image.sink, V4L2_SEL_TGT_CROP, &info->analogCrop); if (ret) return ret; - /* - * IPACameraSensorInfo::analogCrop::x and IPACameraSensorInfo::analogCrop::y - * are defined relatively to the active pixel area, while V4L2's - * TGT_CROP target is defined in respect to the full pixel array. - * - * Compensate it by subtracting the active area offset. - */ - info->analogCrop.x -= activeArea_.x; - info->analogCrop.y -= activeArea_.y; - /* The bit depth and image size depend on the currently applied format. */ V4L2SubdeviceFormat format{}; ret = subdev_->getFormat(streams_.image.source, &format);