From patchwork Mon Jun 30 08:11:16 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Klug X-Patchwork-Id: 23687 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 4BC6AC3237 for ; Mon, 30 Jun 2025 08:11:39 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id D35C868E0A; Mon, 30 Jun 2025 10:11:38 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="HVArykDU"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id D54D668E04 for ; Mon, 30 Jun 2025 10:11:34 +0200 (CEST) Received: from ideasonboard.com (unknown [IPv6:2a00:6020:448c:6c00:883b:eaf8:7aec:d1d4]) by perceval.ideasonboard.com (Postfix) with UTF8SMTPSA id 44C03669; Mon, 30 Jun 2025 10:11:13 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1751271073; bh=+MwTTRmL1WzBMrl5W4FFzvNpjc25Yi3tj+NqEHhjCN0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=HVArykDUIHS2A8N14ueGYx6KOd+BXnNAuGRmNP573YjeUeNQEbFVb1024UjXk90OV Aqluh2ir3tvuhr06pe3ihejfBKqUbQ+7QXPaTzRedNbVuGbJEy03uwOJ6Wo7jH0E/N hAyEo51LnLSSzPNp3n+ayagyadJs6pthhAtJqeSc= From: Stefan Klug To: libcamera-devel@lists.libcamera.org Cc: Stefan Klug Subject: [PATCH v1 1/6] libcamera: pipeline_handler: Move waitingRequests_ into camera class Date: Mon, 30 Jun 2025 10:11:16 +0200 Message-ID: <20250630081126.2384387-2-stefan.klug@ideasonboard.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250630081126.2384387-1-stefan.klug@ideasonboard.com> References: <20250630081126.2384387-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 waiting requests of one camera should not be able to influence queuing to another camera. Therefore change the single waitingRequests_ queue into one queue per camera. Signed-off-by: Stefan Klug Reviewed-by: Umang Jain --- Changes in v1: - Added camera param to doQueueRequests() which allows to remove a loop --- include/libcamera/internal/camera.h | 2 ++ include/libcamera/internal/pipeline_handler.h | 5 +--- src/libcamera/pipeline_handler.cpp | 26 ++++++++++++------- 3 files changed, 19 insertions(+), 14 deletions(-) diff --git a/include/libcamera/internal/camera.h b/include/libcamera/internal/camera.h index 18f5c32a18e4..8a2e9ed5894d 100644 --- a/include/libcamera/internal/camera.h +++ b/include/libcamera/internal/camera.h @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -36,6 +37,7 @@ public: const PipelineHandler *pipe() const { return pipe_.get(); } std::list queuedRequests_; + std::queue waitingRequests_; ControlInfoMap controlInfo_; ControlList properties_; diff --git a/include/libcamera/internal/pipeline_handler.h b/include/libcamera/internal/pipeline_handler.h index 972a2fa65310..be017ad47219 100644 --- a/include/libcamera/internal/pipeline_handler.h +++ b/include/libcamera/internal/pipeline_handler.h @@ -8,7 +8,6 @@ #pragma once #include -#include #include #include #include @@ -89,13 +88,11 @@ private: virtual void disconnect(); void doQueueRequest(Request *request); - void doQueueRequests(); + void doQueueRequests(Camera *camera); std::vector> mediaDevices_; std::vector> cameras_; - std::queue waitingRequests_; - const char *name_; unsigned int useCount_; diff --git a/src/libcamera/pipeline_handler.cpp b/src/libcamera/pipeline_handler.cpp index d84dff3c9f19..dc4086aa9bb5 100644 --- a/src/libcamera/pipeline_handler.cpp +++ b/src/libcamera/pipeline_handler.cpp @@ -363,15 +363,16 @@ void PipelineHandler::stop(Camera *camera) /* Stop the pipeline handler and let the queued requests complete. */ stopDevice(camera); + Camera::Private *data = camera->_d(); + /* Cancel and signal as complete all waiting requests. */ - while (!waitingRequests_.empty()) { - Request *request = waitingRequests_.front(); - waitingRequests_.pop(); + while (!data->waitingRequests_.empty()) { + Request *request = data->waitingRequests_.front(); + data->waitingRequests_.pop(); cancelRequest(request); } /* Make sure no requests are pending. */ - Camera::Private *data = camera->_d(); ASSERT(data->queuedRequests_.empty()); data->requestSequence_ = 0; @@ -414,7 +415,9 @@ void PipelineHandler::registerRequest(Request *request) * Connect the request prepared signal to notify the pipeline handler * when a request is ready to be processed. */ - request->_d()->prepared.connect(this, &PipelineHandler::doQueueRequests); + request->_d()->prepared.connect(this, [&]() { + doQueueRequests(request->_d()->camera()); + }); } /** @@ -444,7 +447,9 @@ void PipelineHandler::queueRequest(Request *request) { LIBCAMERA_TRACEPOINT(request_queue, request); - waitingRequests_.push(request); + Camera *camera = request->_d()->camera(); + Camera::Private *data = camera->_d(); + data->waitingRequests_.push(request); request->_d()->prepare(300ms); } @@ -478,15 +483,16 @@ void PipelineHandler::doQueueRequest(Request *request) * Iterate the list of waiting requests and queue them to the device one * by one if they have been prepared. */ -void PipelineHandler::doQueueRequests() +void PipelineHandler::doQueueRequests(Camera *camera) { - while (!waitingRequests_.empty()) { - Request *request = waitingRequests_.front(); + Camera::Private *data = camera->_d(); + while (!data->waitingRequests_.empty()) { + Request *request = data->waitingRequests_.front(); if (!request->_d()->prepared_) break; doQueueRequest(request); - waitingRequests_.pop(); + data->waitingRequests_.pop(); } } From patchwork Mon Jun 30 08:11:17 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Klug X-Patchwork-Id: 23688 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 E802EC3237 for ; Mon, 30 Jun 2025 08:11:43 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 891E368E0D; Mon, 30 Jun 2025 10:11:43 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="uXXH9s9B"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 3BB3068E00 for ; Mon, 30 Jun 2025 10:11:38 +0200 (CEST) Received: from ideasonboard.com (unknown [IPv6:2a00:6020:448c:6c00:883b:eaf8:7aec:d1d4]) by perceval.ideasonboard.com (Postfix) with UTF8SMTPSA id A95D1669; Mon, 30 Jun 2025 10:11:16 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1751271076; bh=fXH2u5QudviAaFj6PUaJC5vmp1x8ZIBzh2+ntq/idfI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=uXXH9s9BzjDQkC8AQ6QqoaLzBKGehZTfxtRi6UBJCkDARpGpewfgX8bYImVDo0SPq dh991AUwzWBhBRbZKtZd0HJ7M3hupyZsASXwXTWxXRpllScmeTypSRI1ThlKHkORQ5 8gz3SE1xoJDRgKJRGGEgqfSI/jPtPhX8M89xOypE= From: Stefan Klug To: libcamera-devel@lists.libcamera.org Cc: Stefan Klug Subject: [PATCH v1 2/6] libcamera: pipeline_handler: Allow to limit the number of queued requests Date: Mon, 30 Jun 2025 10:11:17 +0200 Message-ID: <20250630081126.2384387-3-stefan.klug@ideasonboard.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250630081126.2384387-1-stefan.klug@ideasonboard.com> References: <20250630081126.2384387-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" Add a maxQueuedRequestsDevice constructor parameter to allow pipeline handler classes to limit the maximum number of requests that get queued to the device in queueRequestDevice(). The default value is set to an arbitrary number of 32 which is big enough for all currently known use cases. Signed-off-by: Stefan Klug --- Changes in v1: - Used a const member variable to carry the maximum number of requests - Improved commit message - Added docs --- include/libcamera/internal/pipeline_handler.h | 4 +++- src/libcamera/pipeline_handler.cpp | 20 ++++++++++++++----- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/include/libcamera/internal/pipeline_handler.h b/include/libcamera/internal/pipeline_handler.h index be017ad47219..e89d6a33e398 100644 --- a/include/libcamera/internal/pipeline_handler.h +++ b/include/libcamera/internal/pipeline_handler.h @@ -33,7 +33,8 @@ class PipelineHandler : public std::enable_shared_from_this, public Object { public: - PipelineHandler(CameraManager *manager); + PipelineHandler(CameraManager *manager, + unsigned int maxQueuedRequestsDevice = 32); virtual ~PipelineHandler(); virtual bool match(DeviceEnumerator *enumerator) = 0; @@ -80,6 +81,7 @@ protected: virtual void releaseDevice(Camera *camera); CameraManager *manager_; + const unsigned int maxQueuedRequestsDevice_; private: void unlockMediaDevices(); diff --git a/src/libcamera/pipeline_handler.cpp b/src/libcamera/pipeline_handler.cpp index dc4086aa9bb5..383c6ad0c4aa 100644 --- a/src/libcamera/pipeline_handler.cpp +++ b/src/libcamera/pipeline_handler.cpp @@ -62,13 +62,17 @@ LOG_DEFINE_CATEGORY(Pipeline) /** * \brief Construct a PipelineHandler instance * \param[in] manager The camera manager + * \param[in] maxQueuedRequestsDevice The maximum number of requests queued to + * the device * * In order to honour the std::enable_shared_from_this<> contract, * PipelineHandler instances shall never be constructed manually, but always * through the PipelineHandlerFactoryBase::create() function. */ -PipelineHandler::PipelineHandler(CameraManager *manager) - : manager_(manager), useCount_(0) +PipelineHandler::PipelineHandler(CameraManager *manager, + unsigned int maxQueuedRequestsDevice) + : manager_(manager), maxQueuedRequestsDevice_(maxQueuedRequestsDevice), + useCount_(0) { } @@ -430,9 +434,9 @@ void PipelineHandler::registerRequest(Request *request) * requests which have to be prepared to make sure they are ready for being * queued to the pipeline handler. * - * The queue of waiting requests is iterated and all prepared requests are - * passed to the pipeline handler in the same order they have been queued by - * calling this function. + * The queue of waiting requests is iterated and up to \a + * maxQueuedRequestsDevice_ prepared requests are passed to the pipeline handler + * in the same order they have been queued by calling this function. * * If a Request fails during the preparation phase or if the pipeline handler * fails in queuing the request to the hardware the request is cancelled. @@ -487,6 +491,9 @@ void PipelineHandler::doQueueRequests(Camera *camera) { Camera::Private *data = camera->_d(); while (!data->waitingRequests_.empty()) { + if (data->queuedRequests_.size() == maxQueuedRequestsDevice_) + break; + Request *request = data->waitingRequests_.front(); if (!request->_d()->prepared_) break; @@ -568,6 +575,9 @@ void PipelineHandler::completeRequest(Request *request) data->queuedRequests_.pop_front(); camera->requestComplete(req); } + + /* Allow any waiting requests to be queued to the pipeline. */ + doQueueRequests(camera); } /** From patchwork Mon Jun 30 08:11:18 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Klug X-Patchwork-Id: 23689 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 99963C3237 for ; Mon, 30 Jun 2025 08:11:46 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 5010268E00; Mon, 30 Jun 2025 10:11:45 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="ufCRbK8t"; 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 3B3E161529 for ; Mon, 30 Jun 2025 10:11:41 +0200 (CEST) Received: from ideasonboard.com (unknown [IPv6:2a00:6020:448c:6c00:883b:eaf8:7aec:d1d4]) by perceval.ideasonboard.com (Postfix) with UTF8SMTPSA id 9F16C1352; Mon, 30 Jun 2025 10:11:19 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1751271079; bh=0FD3dymIMrRUYE8sCRP1lb5ss/0Vt5MX7pZmwpw9qF4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ufCRbK8tNq9IZz8fu1iWGQUfi5ZyMLJHr1EZxKPwyiOHCRZoWZz3QSlVkMEUFsOij n952I7xS6XYPiBxUTFfS8xU1r0YrgtUQmtYL672tEoZefyrexQGEP9hC/HZv1U3OtE EjlOb86kFp99pCCTVaodJq9Wq7VJrLtHq1nntqgA= From: Stefan Klug To: libcamera-devel@lists.libcamera.org Cc: Stefan Klug Subject: [PATCH v1 3/6] pipeline: rkisp1: Limit the maximum number of buffers queued in Date: Mon, 30 Jun 2025 10:11:18 +0200 Message-ID: <20250630081126.2384387-4-stefan.klug@ideasonboard.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250630081126.2384387-1-stefan.klug@ideasonboard.com> References: <20250630081126.2384387-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" To keep the regulation of the algorithms as short as possible and to allow more buffers to be created than the v4l2 device allows to be queued, limit the amount of buffers that get queued into the device to the pipeline depth. Signed-off-by: Stefan Klug --- Changes in v1: - Replaced function overload with constructor param --- src/libcamera/pipeline/rkisp1/rkisp1.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp index 675f0a7490a6..bd14ab237064 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp @@ -155,6 +155,12 @@ private: Transform combinedTransform_; }; +namespace { + +const unsigned int kPipelineDepth = 4; + +}; + class PipelineHandlerRkISP1 : public PipelineHandler { public: @@ -684,7 +690,7 @@ CameraConfiguration::Status RkISP1CameraConfiguration::validate() */ PipelineHandlerRkISP1::PipelineHandlerRkISP1(CameraManager *manager) - : PipelineHandler(manager), hasSelfPath_(true), useDewarper_(false) + : PipelineHandler(manager, kPipelineDepth), hasSelfPath_(true), useDewarper_(false) { } From patchwork Mon Jun 30 08:11:19 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Klug X-Patchwork-Id: 23690 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 CB320C3237 for ; Mon, 30 Jun 2025 08:11:50 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 6C10468E11; Mon, 30 Jun 2025 10:11:50 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="cQsWLDaO"; 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 4879368E0F for ; Mon, 30 Jun 2025 10:11:44 +0200 (CEST) Received: from ideasonboard.com (unknown [IPv6:2a00:6020:448c:6c00:883b:eaf8:7aec:d1d4]) by perceval.ideasonboard.com (Postfix) with UTF8SMTPSA id B2E721352; Mon, 30 Jun 2025 10:11:22 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1751271082; bh=gaAqoFHAde8LKprVSI5/jyKy39lo8PbGwa7J1cmkfuw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=cQsWLDaOAF/YX6Dd8yeEjlyUNhj0MpFipNenyhZYEn0u36SMBO92wfUvUYitI7iVt z7CAJtfQlshkoaTX3epYJsP6uymnDbeu+I7QcKmyXGcok7xPQKFHfa3YMYqsPmP40S P37RLAXWbngS7xax+JF+WhU5NBoBezxumX4Wp8Ss= From: Stefan Klug To: libcamera-devel@lists.libcamera.org Cc: Stefan Klug Subject: [PATCH v1 4/6] pipeline: rkisp1: Properly handle the bufferCount set in the stream configuration Date: Mon, 30 Jun 2025 10:11:19 +0200 Message-ID: <20250630081126.2384387-5-stefan.klug@ideasonboard.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250630081126.2384387-1-stefan.klug@ideasonboard.com> References: <20250630081126.2384387-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 bufferCount is reset to a hardcoded value of 4 in RkISP1Path::validate(). Keep the default value of 4 but do not reset it, if it was changed. Signed-off-by: Stefan Klug --- Changes in v1: - Removed todo comment that was solved by this change --- src/libcamera/pipeline/rkisp1/rkisp1.cpp | 5 +++-- src/libcamera/pipeline/rkisp1/rkisp1_path.cpp | 7 ++----- src/libcamera/pipeline/rkisp1/rkisp1_path.h | 4 +--- 3 files changed, 6 insertions(+), 10 deletions(-) diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp index bd14ab237064..9d7b05490af6 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp @@ -790,6 +790,7 @@ PipelineHandlerRkISP1::generateConfiguration(Camera *camera, return nullptr; cfg.colorSpace = colorSpace; + cfg.bufferCount = kPipelineDepth; config->addConfiguration(cfg); } @@ -1123,14 +1124,14 @@ int PipelineHandlerRkISP1::start(Camera *camera, [[maybe_unused]] const ControlL } if (data->mainPath_->isEnabled()) { - ret = mainPath_.start(); + ret = mainPath_.start(maxQueuedRequestsDevice_); if (ret) return ret; actions += [&]() { mainPath_.stop(); }; } if (hasSelfPath_ && data->selfPath_->isEnabled()) { - ret = selfPath_.start(); + ret = selfPath_.start(maxQueuedRequestsDevice_); if (ret) return ret; } diff --git a/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp b/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp index 64018dc5b2f4..8ea5500d4080 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp @@ -249,7 +249,6 @@ RkISP1Path::generateConfiguration(const CameraSensor *sensor, const Size &size, StreamConfiguration cfg(formats); cfg.pixelFormat = format; cfg.size = streamSize; - cfg.bufferCount = RKISP1_BUFFER_COUNT; return cfg; } @@ -383,7 +382,6 @@ RkISP1Path::validate(const CameraSensor *sensor, cfg->size.boundTo(maxResolution); cfg->size.expandTo(minResolution); - cfg->bufferCount = RKISP1_BUFFER_COUNT; V4L2DeviceFormat format; format.fourcc = video_->toV4L2PixelFormat(cfg->pixelFormat); @@ -480,15 +478,14 @@ int RkISP1Path::configure(const StreamConfiguration &config, return 0; } -int RkISP1Path::start() +int RkISP1Path::start(unsigned int bufferCount) { int ret; if (running_) return -EBUSY; - /* \todo Make buffer count user configurable. */ - ret = video_->importBuffers(RKISP1_BUFFER_COUNT); + ret = video_->importBuffers(bufferCount); if (ret) return ret; diff --git a/src/libcamera/pipeline/rkisp1/rkisp1_path.h b/src/libcamera/pipeline/rkisp1/rkisp1_path.h index 430181d371a7..0b60c499ac64 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1_path.h +++ b/src/libcamera/pipeline/rkisp1/rkisp1_path.h @@ -58,7 +58,7 @@ public: return video_->exportBuffers(bufferCount, buffers); } - int start(); + int start(unsigned int bufferCount); void stop(); int queueBuffer(FrameBuffer *buffer) { return video_->queueBuffer(buffer); } @@ -69,8 +69,6 @@ private: void populateFormats(); Size filterSensorResolution(const CameraSensor *sensor); - static constexpr unsigned int RKISP1_BUFFER_COUNT = 4; - const char *name_; bool running_; From patchwork Mon Jun 30 08:11:20 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Stefan Klug X-Patchwork-Id: 23691 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 8E7A4C3293 for ; Mon, 30 Jun 2025 08:11:53 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id B795E68E12; Mon, 30 Jun 2025 10:11:52 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="a9WL0VpV"; 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 247FD68E04 for ; Mon, 30 Jun 2025 10:11:47 +0200 (CEST) Received: from ideasonboard.com (unknown [IPv6:2a00:6020:448c:6c00:883b:eaf8:7aec:d1d4]) by perceval.ideasonboard.com (Postfix) with UTF8SMTPSA id 8B9CE1352; Mon, 30 Jun 2025 10:11:25 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1751271085; bh=D/M37FW2q6WdsWBGwEXaFTX/NL41SS2QvkI5Z2chawI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=a9WL0VpVw8B2/fPhFyoQM984cgSdPbF1rrGWVrfcu6wckmb2N+DvlR2voUuawu2RD OX7uJUJhJEd+rqV36UJ46w46pDRAjAGOhINJHjA5J5sXNISp658S3V6MTfNgbhRu4Y CSshyybZ3p1R9sBYBMf09LWywWh0yrVcTmkqvhMk= From: Stefan Klug To: libcamera-devel@lists.libcamera.org Cc: Stefan Klug , =?utf-8?b?TsOtY29sYXMgRi4g?= =?utf-8?q?R=2E_A=2E_Prado?= , Paul Elder , =?utf-8?q?Sven_P=C3=BCschel?= Subject: [PATCH v1 5/6] libcamera: pipeline: rkisp1: Don't rely on bufferCount Date: Mon, 30 Jun 2025 10:11:20 +0200 Message-ID: <20250630081126.2384387-6-stefan.klug@ideasonboard.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250630081126.2384387-1-stefan.klug@ideasonboard.com> References: <20250630081126.2384387-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" From: Nícolas F. R. A. Prado Currently the rkisp1 pipeline handler relies on bufferCount to decide on the number of parameter and statistics buffers to allocate internally. Instead, the number of internal buffers should be the minimum required by the pipeline to keep the requests flowing, in order to avoid wasting memory. Stop relying on bufferCount for these numbers and instead set them to kPipelineDepth, as this already limits the number of buffers queued to the driver. Signed-off-by: Nícolas F. R. A. Prado Signed-off-by: Paul Elder Signed-off-by: Sven Püschel --- src/libcamera/pipeline/rkisp1/rkisp1.cpp | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp index 9d7b05490af6..0106dcff23a0 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp @@ -157,6 +157,10 @@ private: namespace { +/* + * This many internal buffers (or rather parameter and statistics buffer + * pairs) ensures that the pipeline runs smoothly, without frame drops. + */ const unsigned int kPipelineDepth = 4; }; @@ -990,24 +994,19 @@ int PipelineHandlerRkISP1::allocateBuffers(Camera *camera) unsigned int ipaBufferId = 1; int ret; - unsigned int maxCount = std::max({ - data->mainPathStream_.configuration().bufferCount, - data->selfPathStream_.configuration().bufferCount, - }); - if (!isRaw_) { - ret = param_->allocateBuffers(maxCount, ¶mBuffers_); + ret = param_->allocateBuffers(kPipelineDepth, ¶mBuffers_); if (ret < 0) goto error; - ret = stat_->allocateBuffers(maxCount, &statBuffers_); + ret = stat_->allocateBuffers(kPipelineDepth, &statBuffers_); if (ret < 0) goto error; } /* If the dewarper is being used, allocate internal buffers for ISP. */ if (useDewarper_) { - ret = mainPath_.exportBuffers(maxCount, &mainPathBuffers_); + ret = mainPath_.exportBuffers(kPipelineDepth, &mainPathBuffers_); if (ret < 0) goto error; From patchwork Mon Jun 30 08:11:21 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Klug X-Patchwork-Id: 23692 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 885D1C3237 for ; Mon, 30 Jun 2025 08:11:55 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 4407F68E0D; Mon, 30 Jun 2025 10:11:54 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="CQNp98F7"; 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 6EF0B68E12 for ; Mon, 30 Jun 2025 10:11:50 +0200 (CEST) Received: from ideasonboard.com (unknown [IPv6:2a00:6020:448c:6c00:883b:eaf8:7aec:d1d4]) by perceval.ideasonboard.com (Postfix) with UTF8SMTPSA id CFEBD16B8; Mon, 30 Jun 2025 10:11:28 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1751271088; bh=TgrIkSU6tKIpjOwsgYCV1nBzb/y3gOE6vyBU1pvFPmI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=CQNp98F7CWOCV4LwaJX5QzFOUIq/meI/cbgll6T0J2DbFNc+tgTjx1sCQofd7p2pS dWLh0MBviVvy2bMnShfo6NrjN05w9I8KyaG42QLvhI8cp2BvoPsKYv9We1XPPKqJGT ByDWKP0mZgPfPoyvffEAu0d7r/CcyWA5Ni18J5O4= From: Stefan Klug To: libcamera-devel@lists.libcamera.org Cc: Stefan Klug , Kieran Bingham Subject: [PATCH v1 6/6] libcamera: pipeline_handler: cancel waiting requests first Date: Mon, 30 Jun 2025 10:11:21 +0200 Message-ID: <20250630081126.2384387-7-stefan.klug@ideasonboard.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250630081126.2384387-1-stefan.klug@ideasonboard.com> References: <20250630081126.2384387-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" From: Kieran Bingham When stopping a camera, we may now find that there are requests queued to the camera but not yet available in the pipeline handler. These are "waitingReqeusts" which are not yet queued to the device. While stopping a camera, we ask the pipeline to stop with stopDevice() and then cancel any waiting requests after. This however can lead to a race where having stopped the camera and completed the requests, the pipeline may try to further consume requests from the waiting lists. Therefore empty the waitingRequests queue before stopping the device and cancel the waitingRequests afterwards. Signed-off-by: Kieran Bingham Signed-off-by: Stefan Klug Reviewed-by: Kieran Bingham --- src/libcamera/pipeline_handler.cpp | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/libcamera/pipeline_handler.cpp b/src/libcamera/pipeline_handler.cpp index 383c6ad0c4aa..207a2bae96d6 100644 --- a/src/libcamera/pipeline_handler.cpp +++ b/src/libcamera/pipeline_handler.cpp @@ -364,20 +364,28 @@ void PipelineHandler::unlockMediaDevices() */ void PipelineHandler::stop(Camera *camera) { + /* + * Take all waiting requests so that they are not requeued in response + * to completeRequest() being called inside stopDevice(). Cancel them + * after the device to keep them in order. + */ + Camera::Private *data = camera->_d(); + std::queue waitingRequests; + waitingRequests.swap(data->waitingRequests_); + /* Stop the pipeline handler and let the queued requests complete. */ stopDevice(camera); - Camera::Private *data = camera->_d(); - /* Cancel and signal as complete all waiting requests. */ - while (!data->waitingRequests_.empty()) { - Request *request = data->waitingRequests_.front(); - data->waitingRequests_.pop(); + while (!waitingRequests.empty()) { + Request *request = waitingRequests.front(); + waitingRequests.pop(); cancelRequest(request); } /* Make sure no requests are pending. */ ASSERT(data->queuedRequests_.empty()); + ASSERT(data->waitingRequests_.empty()); data->requestSequence_ = 0; }