From patchwork Wed Aug 26 08:23:25 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?UsOzYmVydCBCb8W+aWs=?= X-Patchwork-Id: 28100 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 3DE15C333C for ; Wed, 26 Aug 2026 08:33:32 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 9B0E36843F; Wed, 26 Aug 2026 10:33:28 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="N+oQk21v"; dkim-atps=neutral Received: from mail-ej1-x62b.google.com (mail-ej1-x62b.google.com [IPv6:2a00:1450:4864:20::62b]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 692E068406 for ; Wed, 26 Aug 2026 10:23:37 +0200 (CEST) Received: by mail-ej1-x62b.google.com with SMTP id a640c23a62f3a-c1c52d920b8so77668566b.2 for ; Wed, 26 Aug 2026 01:23:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1787732617; x=1788337417; 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:content-type; bh=b0+DHPFnbUJqxMG7LCCRZqbuEFKsg5PZWPtq/mGAJ7U=; b=N+oQk21vEyN7GU1TFol+xxaOYYHNshuEETUOiBaQtZp1uKuPLpGphL71Ro0hK0o7XP D2WeCmMAp/bVLy20aHCwdKNjPB27NcDgsgRB76E/OQR2XbR5Prb1qniQUr3X1DkCgN18 0fzk5KwGm+hXpCICuwsIjR+DcUK/aen2G+s4oWJFu14qVPQVAcfc4cVhjM816jQmInpr kUYfpoS3zJgz+4gJMu6oBmC7eZ1qT/K7lpKnIqT8JnY277qHqYTucWDKNGMSgFFdN7NC n+NaYAmwCTIYNJ4SCD60zcgRfQBRW2JUet1eMnNB6bXoobrua/ms9LLPo/xhCqht5pdL bASA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1787732617; x=1788337417; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=b0+DHPFnbUJqxMG7LCCRZqbuEFKsg5PZWPtq/mGAJ7U=; b=XbJuWVJUmo2vdKa54KquzCsNrp0RZWv+yUtP77JbN9dso7ASRKPb/kYy1VUaqOX7oF U4xkqpF7YvgZs5E/rmxv7z3dK98tM93HuEKrPA5GlA3dUKgIVgXUwopAHVNzmMrehD4w smfZsQTRj9k/UV/1QNORGPEnenlm+nNhz8sGGq5dx0YzUKH88KnoaqFtMbXzhKIosO8Y TKRT4rKSqan7N+FTrmRo4zdo5uEBV5NpsAXReDQHGrQQVUzG6YZFG4j8yLxyTaWzQU4d SK7sOO1sT72fYtAoyV6IDCZFUN1BJvai3YbjiV9unU6uxRSwHX6bpLUdrwVAqKbx+zTj 2wbQ== X-Gm-Message-State: AFuF++nw5iJjCWDtSC77A2rpICIgaD+GzQBmT7KGYcOuKBO2TlTUyPhg kFeEaoCQ12rwWD9fSQbLrgB35eRorgeLbSt48G8YK2mTcKvbguW5eaAjEeEtNpYMzog= X-Gm-Gg: AR+sD11nIAYdKVUrg+7yBeY7Ak/URoRuTQdA8Y3mMTIH/9ZQfjs32fR8+3VlHmxKbbc +1it8ZMMXxIhVLlHpHu4vtnBXSl+Ix85TMuQIZ88WJZqjCv9Nm8t3TIVHwPUtKJxVCfY/hei6V5 tstKljUeRTAzXFbWUavvud9dUCnU9fJbeSJ38tMoavXfaCt+ReoCmZBkTNANrsxC8iqrt3W1Cf9 RnoqPWCz+FQUaW+Uyhkmo2jNsTxylc2Dpwsfvg+qhEB1WlmT5fqwbbbVLavfKr1Ki7VKlg1II1F oQNz35mI4Z7Bj1ZgqHjy0xRpL56bOuAABgIIuIFRf9eT9bvzXGgf2O8hFd7pkuVYysn6dJethFN OHYg/Gyx/w4tHTA88UV8gwptuKTJ3DQQxslARpqRu/89AeYxb3hvg3OR5JpQbClO55b1D05xMJm JwYSK/AORCWpzgwLgijwFbk7ydxdBnhlM1OScj9mInc0kmcaKL5nOU+oqPb+yLqlc7TAD2Nr69S ZGfT6+VluQUEO7Zg9eOwkmGMQXuNPs5qNKiDviaOuTf9++uX672HCDDWlxAQHwVvDJA+o9SB6a2 kgc8wJsJX/2BqO0= X-Received: by 2002:a17:907:980e:b0:c25:2f12:1441 with SMTP id a640c23a62f3a-c252f121647mr11850166b.12.1787732616857; Wed, 26 Aug 2026 01:23:36 -0700 (PDT) Received: from robert-83cx (static-dsl-191.87-197-115.telecom.sk. [87.197.115.191]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-c250a5d69a7sm554222766b.8.2026.08.26.01.23.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 26 Aug 2026 01:23:36 -0700 (PDT) From: Robert Bozik To: libcamera-devel@lists.libcamera.org Cc: Kieran Bingham , Milan Zamazal , =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= , Hans de Goede , Robert Mader , Bryan O'Donoghue , Laurent Pinchart , Robert Bozik Subject: [PATCH 4/7] pipeline: simple: Pass the startup controls to the software ISP IPA Date: Wed, 26 Aug 2026 10:23:25 +0200 Message-ID: <20260826082328.24176-5-robertbozik@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260826082328.24176-1-robertbozik@gmail.com> References: <20260826082328.24176-1-robertbozik@gmail.com> MIME-Version: 1.0 X-Mailman-Approved-At: Wed, 26 Aug 2026 10:33:21 +0200 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 controls passed to Camera::start() were dropped by the simple pipeline handler, so applications that configure the camera at start, such as libcamerasrc with its framerate caps and the PipeWire libcamera source, had no effect on the software ISP: FrameDurationLimits, AWB mode or colour gains set that way were silently ignored. Extend the software ISP and its IPA start() with the control list, and have the IPA feed the controls through the algorithms' queueRequest() handlers with a throwaway frame context, so that they end up in the active state exactly as per-request controls do. Signed-off-by: Robert Bozik --- .../libcamera/internal/software_isp/software_isp.h | 2 +- include/libcamera/ipa/softisp.mojom | 2 +- src/ipa/softisp/softisp.cpp | 13 +++++++++++-- src/libcamera/pipeline/simple/simple.cpp | 4 ++-- src/libcamera/software_isp/software_isp.cpp | 5 +++-- 5 files changed, 18 insertions(+), 8 deletions(-) diff --git a/include/libcamera/internal/software_isp/software_isp.h b/include/libcamera/internal/software_isp/software_isp.h index da893d24..9f3227d5 100644 --- a/include/libcamera/internal/software_isp/software_isp.h +++ b/include/libcamera/internal/software_isp/software_isp.h @@ -73,7 +73,7 @@ public: void processStats(const uint32_t frame, const uint32_t bufferId, const ControlList &sensorControls); - int start(); + int start(const ControlList &controls); void stop(); void queueRequest(const uint32_t frame, const ControlList &controls); diff --git a/include/libcamera/ipa/softisp.mojom b/include/libcamera/ipa/softisp.mojom index a892d84f..d9c9842f 100644 --- a/include/libcamera/ipa/softisp.mojom +++ b/include/libcamera/ipa/softisp.mojom @@ -19,7 +19,7 @@ interface IPASoftIspInterface { libcamera.IPACameraSensorInfo sensorInfo, libcamera.ControlInfoMap sensorControls) => (int32 ret, libcamera.ControlInfoMap ipaControls, bool ccmEnabled); - start() => (int32 ret); + start(libcamera.ControlList controls) => (int32 ret); stop(); configure(IPAConfigInfo configInfo) => (int32 ret); diff --git a/src/ipa/softisp/softisp.cpp b/src/ipa/softisp/softisp.cpp index 612f9dfa..6d6b80d5 100644 --- a/src/ipa/softisp/softisp.cpp +++ b/src/ipa/softisp/softisp.cpp @@ -61,7 +61,7 @@ public: bool *ccmEnabled) override; int configure(const IPAConfigInfo &configInfo) override; - int start() override; + int start(const ControlList &controls) override; void stop() override; void queueRequest(const uint32_t frame, const ControlList &controls) override; @@ -301,8 +301,17 @@ int IPASoftIsp::configure(const IPAConfigInfo &configInfo) return 0; } -int IPASoftIsp::start() +int IPASoftIsp::start(const ControlList &controls) { + /* + * Apply the startup controls through the algorithms, as if they had + * been queued with a request. The frame context is a throwaway, the + * algorithms record what matters in the active state. + */ + IPAFrameContext frameContext{}; + for (const auto &algo : algorithms()) + algo->queueRequest(context_, 0, frameContext, controls); + return 0; } diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp index 0a0cfc55..4793a522 100644 --- a/src/libcamera/pipeline/simple/simple.cpp +++ b/src/libcamera/pipeline/simple/simple.cpp @@ -1647,7 +1647,7 @@ int SimplePipelineHandler::exportFrameBuffers(Camera *camera, Stream *stream, return data->video_->exportBuffers(count, buffers); } -int SimplePipelineHandler::start(Camera *camera, [[maybe_unused]] const ControlList *controls) +int SimplePipelineHandler::start(Camera *camera, const ControlList *controls) { SimpleCameraData *data = cameraData(camera); V4L2VideoDevice *video = data->video_; @@ -1705,7 +1705,7 @@ int SimplePipelineHandler::start(Camera *camera, [[maybe_unused]] const ControlL if (data->converter_) ret = data->converter_->start(); else if (data->swIsp_) - ret = data->swIsp_->start(); + ret = data->swIsp_->start(controls ? *controls : ControlList()); else ret = 0; diff --git a/src/libcamera/software_isp/software_isp.cpp b/src/libcamera/software_isp/software_isp.cpp index ae86c20a..432cab24 100644 --- a/src/libcamera/software_isp/software_isp.cpp +++ b/src/libcamera/software_isp/software_isp.cpp @@ -374,11 +374,12 @@ int SoftwareIsp::queueBuffers(uint32_t frame, FrameBuffer *input, /** * \brief Starts the Software ISP streaming operation + * \param[in] controls The controls to apply before the first frame * \return 0 on success, any other value indicates an error */ -int SoftwareIsp::start() +int SoftwareIsp::start(const ControlList &controls) { - int ret = ipa_->start(); + int ret = ipa_->start(controls); if (ret) return ret;