From patchwork Mon Apr 28 09:02:42 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Sven_P=C3=BCschel?= X-Patchwork-Id: 23290 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 95B74C3329 for ; Mon, 28 Apr 2025 09:05:41 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 9E39768B41; Mon, 28 Apr 2025 11:05:40 +0200 (CEST) Received: from metis.whiteo.stw.pengutronix.de (metis.whiteo.stw.pengutronix.de [IPv6:2a0a:edc0:2:b01:1d::104]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 021B668B2A for ; Mon, 28 Apr 2025 11:05:08 +0200 (CEST) Received: from ptz.office.stw.pengutronix.de ([2a0a:edc0:0:900:1d::77] helo=peter.guest.stw.pengutronix.de) by metis.whiteo.stw.pengutronix.de with esmtp (Exim 4.92) (envelope-from ) id 1u9KQG-0001au-Lm; Mon, 28 Apr 2025 11:05:08 +0200 From: =?utf-8?q?Sven_P=C3=BCschel?= To: libcamera-devel@lists.libcamera.org Cc: =?utf-8?b?TsOtY29sYXMgRi4gUi4gQS4gUHJhZG8=?= , Laurent Pinchart , =?utf-8?q?Sven_P=C3=BCschel?= Subject: [PATCH v11 17/19] libcamera: pipeline: rkisp1: Add internal request queue Date: Mon, 28 Apr 2025 11:02:42 +0200 Message-ID: <20250428090413.38234-18-s.pueschel@pengutronix.de> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250428090413.38234-1-s.pueschel@pengutronix.de> References: <20250428090413.38234-1-s.pueschel@pengutronix.de> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 2a0a:edc0:0:900:1d::77 X-SA-Exim-Mail-From: s.pueschel@pengutronix.de X-SA-Exim-Scanned: No (on metis.whiteo.stw.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: libcamera-devel@lists.libcamera.org 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 Add an internal queue that stores requests until there are internal buffers and V4L2 buffer slots available. This avoids the need to cancel requests when there is a shortage of said buffers. Signed-off-by: Nícolas F. R. A. Prado Reviewed-by: Laurent Pinchart Signed-off-by: Sven Püschel --- Changes in v11: - Added from https://lists.libcamera.org/pipermail/libcamera-devel/2021-September/024121.html --- src/libcamera/pipeline/rkisp1/rkisp1.cpp | 81 ++++++++++++++++++------ 1 file changed, 62 insertions(+), 19 deletions(-) diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp index 623bcfe5..d48da4e2 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp @@ -101,6 +101,9 @@ public: const PipelineHandlerRkISP1 *pipe() const; int loadIPA(unsigned int hwRevision); + void queuePendingRequests(); + void cancelPendingRequests(); + Stream mainPathStream_; Stream selfPathStream_; std::unique_ptr sensor_; @@ -115,6 +118,7 @@ public: std::unique_ptr ipa_; ControlInfoMap ipaControls_; + std::queue pendingRequests_; private: void paramsComputed(unsigned int frame, unsigned int bytesused); @@ -254,12 +258,12 @@ RkISP1FrameInfo *RkISP1Frames::create(const RkISP1CameraData *data, Request *req if (!isRaw) { if (pipe_->availableParamBuffers_.empty()) { - LOG(RkISP1, Error) << "Parameters buffer underrun"; + LOG(RkISP1, Debug) << "Parameters buffer underrun"; return nullptr; } if (pipe_->availableStatBuffers_.empty()) { - LOG(RkISP1, Error) << "Statistic buffer underrun"; + LOG(RkISP1, Debug) << "Statistic buffer underrun"; return nullptr; } @@ -447,6 +451,56 @@ void RkISP1CameraData::metadataReady(unsigned int frame, const ControlList &meta pipe()->tryCompleteRequest(info); } +void RkISP1CameraData::queuePendingRequests() +{ + while (!pendingRequests_.empty()) { + Request *request = pendingRequests_.front(); + + /* + * If there aren't internal buffers available, we break and try + * again later. If there are, we're guaranteed to also have V4L2 + * buffer slots available to queue the request, since we should + * always have more (or equal) buffer slots than internal + * buffers. + */ + RkISP1FrameInfo *info = frameInfo_.create(this, request, pipe()->isRaw_); + if (!info) + break; + + ipa_->queueRequest(frame_, request->controls()); + if (pipe()->isRaw_) { + if (info->mainPathBuffer) + mainPath_->queueBuffer(info->mainPathBuffer); + + if (selfPath_ && info->selfPathBuffer) + selfPath_->queueBuffer(info->selfPathBuffer); + } else { + ipa_->computeParams(frame_, info->paramBuffer->cookie()); + } + + frame_++; + + pendingRequests_.pop(); + } +} + +void RkISP1CameraData::cancelPendingRequests() +{ + while (!pendingRequests_.empty()) { + Request *request = pendingRequests_.front(); + + for (auto it : request->buffers()) { + FrameBuffer *buffer = it.second; + buffer->_d()->cancel(); + pipe()->completeBuffer(request, buffer); + } + + pipe()->completeRequest(request); + + pendingRequests_.pop(); + } +} + /* ----------------------------------------------------------------------------- * Camera Configuration */ @@ -1168,6 +1222,8 @@ void PipelineHandlerRkISP1::stopDevice(Camera *camera) dewarper_->stop(); } + data->cancelPendingRequests(); + ASSERT(data->queuedRequests_.empty()); data->frameInfo_.clear(); @@ -1180,23 +1236,8 @@ int PipelineHandlerRkISP1::queueRequestDevice(Camera *camera, Request *request) { RkISP1CameraData *data = cameraData(camera); - RkISP1FrameInfo *info = data->frameInfo_.create(data, request, isRaw_); - if (!info) - return -ENOENT; - - data->ipa_->queueRequest(data->frame_, request->controls()); - if (isRaw_) { - if (info->mainPathBuffer) - data->mainPath_->queueBuffer(info->mainPathBuffer); - - if (data->selfPath_ && info->selfPathBuffer) - data->selfPath_->queueBuffer(info->selfPathBuffer); - } else { - data->ipa_->computeParams(data->frame_, - info->paramBuffer->cookie()); - } - - data->frame_++; + data->pendingRequests_.push(request); + data->queuePendingRequests(); return 0; } @@ -1481,6 +1522,8 @@ void PipelineHandlerRkISP1::tryCompleteRequest(RkISP1FrameInfo *info) data->frameInfo_.destroy(info->frame); completeRequest(request); + + data->queuePendingRequests(); } void PipelineHandlerRkISP1::imageBufferReady(FrameBuffer *buffer)