From patchwork Sat Oct 24 11:22:23 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Robert Mader X-Patchwork-Id: 28597 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 26EECC3261 for ; Sat, 24 Oct 2026 11:22:39 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id F07CE68FBC; Sat, 24 Oct 2026 13:22:37 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=collabora.com header.i=robert.mader@collabora.com header.b="Lf/yhuFX"; dkim-atps=neutral Received: from sender5-op-o11.zoho.com (sender5-op-o11.zoho.com [165.173.182.11]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 8627868ECB for ; Sat, 24 Oct 2026 13:22:35 +0200 (CEST) ARC-Seal: i=1; a=rsa-sha256; t=1792840950; cv=none; d=zohomail.com; s=zohoarc; b=Gicikcli8tJYKRV0UJm479trZxhmQHKVpyKMxyzak+AQ6dEMNYiLnOxM3/Q5QmAOBJgBazSjzkkFdCIh1p4R4sGdy+8GVyNn40EqhMu3w3Dj2r3lPV4uRD9vzhEihJjPbd2ywTFkTgwHwY0G6kZhugZOdDW+GZgBAr8gROo+YMQ= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1792840950; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:MIME-Version:Message-ID:Subject:Subject:To:To:Message-Id:Reply-To; bh=m/3t9IhrnzXPfd5uTzf7r9+lI9WWqyxwkaXL0NxqCUI=; b=EwnSnqDsQApUhf33L+vpJAx/EVYolKzak6+pshxYlWLOMjhSrka1TXnLlSTO1ma8POnU+bpaTb3GszwVOXK+MNbxRJ6XuYT+IM7xxuPRedsbkHYkNP4S1Jxj+MP2AfCLQUxXAcjJI81nxnsdXu/+1twemFPT2eX8ZffuUZiwSR4= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass header.i=collabora.com; spf=pass smtp.mailfrom=robert.mader@collabora.com; dmarc=pass header.from= DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; t=1792840950; s=zohomail; d=collabora.com; i=robert.mader@collabora.com; h=From:From:To:To:Cc:Cc:Subject:Subject:Date:Date:Message-ID:MIME-Version:Content-Transfer-Encoding:Message-Id:Reply-To; bh=m/3t9IhrnzXPfd5uTzf7r9+lI9WWqyxwkaXL0NxqCUI=; b=Lf/yhuFX83Jws3e45/VOiDlqPJpb/RTYsp9GQ7/3LZrbCon63JmE70MU6YM8coFM EgHmWjfPxqDFn3GP+fb07OEaVC007qIteVf2ftgmtHlYLNNEpvpoZGoVg6RF26m7ENS mHDYd45UjQJ8380VHfbVKRtGE44pK9p3HLG0qpQw= Received: by smtp.zohomail.com with SMTPS id 179284094871937.15245784874298; Sat, 24 Oct 2026 04:22:28 -0700 (PDT) From: Robert Mader To: libcamera-devel@lists.libcamera.org Cc: Robert Mader Subject: [PATCH v2] libcamera: software_isp: Allow limiting output sizes Date: Sat, 24 Oct 2026 13:22:23 +0200 Message-ID: <20261024112223.207603-1-robert.mader@collabora.com> X-Mailer: git-send-email 2.56.0 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" There are various scenarios where it can be useful to control the output sizes of the softisp inside libcamera without rebuilding the project. Examples include: - Debugging and testing when one can't fully control the client - Forcing well working sizes on devices where the GPU/CPU are not strong enough for typically client-picked sizes. This can be especially useful on mobile devices Add a new "options" block to softisp tuning files, to be used like shown below: >options: > min_output_width: 640 > min_output_height: 480 > max_output_width: 1920 > max_output_height: 1080 Signed-off-by: Robert Mader --- Changes in v2: - Use tuning files instead of the global config - Fix typo in commit message Context: I plan to use this as convenience feature in Nura (formerly postmarketOS), making it easy to ship device specific configuration files without needing libcamera-specific downstream changes to the kernel. To me the feature seems useful enough to upstream it, though. --- .../internal/software_isp/software_isp.h | 1 + include/libcamera/ipa/softisp.mojom | 3 ++- src/ipa/softisp/softisp.cpp | 22 +++++++++++++++++-- src/libcamera/software_isp/software_isp.cpp | 8 +++++-- 4 files changed, 29 insertions(+), 5 deletions(-) diff --git a/include/libcamera/internal/software_isp/software_isp.h b/include/libcamera/internal/software_isp/software_isp.h index b64910637dcc..12e70ec12481 100644 --- a/include/libcamera/internal/software_isp/software_isp.h +++ b/include/libcamera/internal/software_isp/software_isp.h @@ -102,6 +102,7 @@ private: DmaBufAllocator dmaHeap_; bool ccmEnabled_; bool lscEnabled_; + SizeRange outputSizeLimits_; std::unique_ptr ipa_; std::deque queuedInputBuffers_; diff --git a/include/libcamera/ipa/softisp.mojom b/include/libcamera/ipa/softisp.mojom index e42742ed7f6d..52f60d902b25 100644 --- a/include/libcamera/ipa/softisp.mojom +++ b/include/libcamera/ipa/softisp.mojom @@ -20,7 +20,8 @@ interface IPASoftIspInterface { libcamera.ControlInfoMap sensorControls) => (int32 ret, libcamera.ControlInfoMap ipaControls, - bool ccmEnabled, bool lscEnabled); + bool ccmEnabled, bool lscEnabled, + libcamera.SizeRange sizeLimits); start() => (int32 ret); stop(); configure(IPAConfigInfo configInfo) diff --git a/src/ipa/softisp/softisp.cpp b/src/ipa/softisp/softisp.cpp index 00249a300430..a166176b90c0 100644 --- a/src/ipa/softisp/softisp.cpp +++ b/src/ipa/softisp/softisp.cpp @@ -59,7 +59,8 @@ public: const ControlInfoMap &sensorControls, ControlInfoMap *ipaControls, bool *ccmEnabled, - bool *lscEnabled) override; + bool *lscEnabled, + SizeRange *sizeLimits) override; int configure(const IPAConfigInfo &configInfo, ControlInfoMap *ipaControls) override; @@ -99,7 +100,8 @@ int IPASoftIsp::init(const IPASettings &settings, const ControlInfoMap &sensorControls, ControlInfoMap *ipaControls, bool *ccmEnabled, - bool *lscEnabled) + bool *lscEnabled, + SizeRange *sizeLimits) { context_.camHelper = CameraSensorHelperFactoryBase::create(settings.sensorModel); if (!context_.camHelper) { @@ -186,6 +188,22 @@ int IPASoftIsp::init(const IPASettings &settings, ControlInfoMap::Map ctrlMap = context_.ctrlMap; *ipaControls = ControlInfoMap(std::move(ctrlMap), controls::controls); + sizeLimits->min = Size(0, 0); + sizeLimits->max = Size(std::numeric_limits::max(), + std::numeric_limits::max()); + if (data->contains("options")) { + const ValueNode *options = &(*data)["options"]; + + if (options->contains("min_output_width")) + sizeLimits->min.width = (*options)["min_output_width"].get(0); + if (options->contains("min_output_heigth")) + sizeLimits->min.height = (*options)["min_output_heigth"].get(0); + if (options->contains("max_output_width")) + sizeLimits->max.width = (*options)["max_output_width"].get(0); + if (options->contains("max_output_heigth")) + sizeLimits->max.height = (*options)["max_output_heigth"].get(0); + } + return 0; } diff --git a/src/libcamera/software_isp/software_isp.cpp b/src/libcamera/software_isp/software_isp.cpp index 627625b4f54f..218660ed8510 100644 --- a/src/libcamera/software_isp/software_isp.cpp +++ b/src/libcamera/software_isp/software_isp.cpp @@ -164,7 +164,8 @@ SoftwareIsp::SoftwareIsp(PipelineHandler *pipe, const CameraSensor *sensor, sensor->controls(), ipaControls, &ccmEnabled_, - &lscEnabled_); + &lscEnabled_, + &outputSizeLimits_); if (ret) { LOG(SoftwareIsp, Error) << "IPA init failed"; debayer_.reset(); @@ -244,7 +245,10 @@ SizeRange SoftwareIsp::sizes(PixelFormat inputFormat, const Size &inputSize) { ASSERT(debayer_); - return debayer_->sizes(inputFormat, inputSize); + SizeRange sizes = debayer_->sizes(inputFormat, inputSize); + sizes.min = sizes.min.expandTo(outputSizeLimits_.min).alignUpTo(sizes.hStep, sizes.vStep); + sizes.max = sizes.max.boundTo(outputSizeLimits_.max).alignDownTo(sizes.hStep, sizes.vStep); + return sizes; } /**