From patchwork Thu Jul 24 06:52:56 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dan Scally X-Patchwork-Id: 23927 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 B088EC332C for ; Thu, 24 Jul 2025 06:53:32 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 962F06908C; Thu, 24 Jul 2025 08:53:30 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="afxSiS23"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id D56E669085 for ; Thu, 24 Jul 2025 08:53:16 +0200 (CEST) Received: from mail.ideasonboard.com (cpc141996-chfd3-2-0-cust928.12-3.cable.virginm.net [86.13.91.161]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 0081017D1; Thu, 24 Jul 2025 08:52:37 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1753339958; bh=WWatLoSknEiLUU87NIzW3oSNdF86COOhJbGRZ4QS3ss=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=afxSiS23b5MktkkN7maMhWAPE22cuHD7D/CmVCJjcLFEkPjy+8UT2F2wpIJYpD9EX zYes41mEqzwhX77FEkOjJaHHh2yroG7DcQScdJeVkRnYZ1znNbR3thY5vAyXADdKsa 6JyRgCcqy6SpIVUq81+0+/g//p26qA9ZWPGmgW00= From: Daniel Scally To: libcamera-devel@lists.libcamera.org Cc: Daniel Scally Subject: [PATCH 10/10] libcamera: mali-c55: Match for memory input media entities Date: Thu, 24 Jul 2025 07:52:56 +0100 Message-Id: <20250724065256.75175-11-dan.scally@ideasonboard.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250724065256.75175-1-dan.scally@ideasonboard.com> References: <20250724065256.75175-1-dan.scally@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" Updating the Pipeline Handler's match() function to search for the entities necessary for memory input mode and create a CameraData instance for that camera if one is found. Signed-off-by: Daniel Scally --- src/libcamera/pipeline/mali-c55/mali-c55.cpp | 100 ++++++++++++++++--- 1 file changed, 85 insertions(+), 15 deletions(-) diff --git a/src/libcamera/pipeline/mali-c55/mali-c55.cpp b/src/libcamera/pipeline/mali-c55/mali-c55.cpp index 2a396950..e2f31e77 100644 --- a/src/libcamera/pipeline/mali-c55/mali-c55.cpp +++ b/src/libcamera/pipeline/mali-c55/mali-c55.cpp @@ -1817,6 +1817,45 @@ bool PipelineHandlerMaliC55::registerSensorCamera(MediaLink *ispLink) return true; } +bool PipelineHandlerMaliC55::registerMemoryInputCamera() +{ + MediaEntity *sensorEntity; + int ret; + + std::unique_ptr data = std::make_unique(this); + + data->cru_ = std::make_unique(); + ret = data->cru_->init(cruMedia_, &sensorEntity); + if (ret) + return false; + + if (data->init(sensorEntity)) + return false; + + data->cru_->setSensorAndCSI2Pointers(data->sensor_, data->csi_); + + data->properties_ = data->sensor_->properties(); + + const CameraSensorProperties::SensorDelays &delays = data->sensor_->sensorDelays(); + std::unordered_map params = { + { V4L2_CID_ANALOGUE_GAIN, { delays.gainDelay, false } }, + { V4L2_CID_EXPOSURE, { delays.exposureDelay, false } }, + }; + + data->delayedCtrls_ = + std::make_unique(data->sensor_->device(), + params); + isp_->frameStart.connect(data->delayedCtrls_.get(), + &DelayedControls::applyControls); + data->cru_->output()->bufferReady.connect(this, &PipelineHandlerMaliC55::cruBufferReady); + input_->bufferReady.connect(data->cru_.get(), &RZG2LCRU::cruReturnBuffer); + + if (!registerMaliCamera(std::move(data), sensorEntity->name())) + return false; + + return true; +} + bool PipelineHandlerMaliC55::match(DeviceEnumerator *enumerator) { const MediaPad *ispSink; @@ -1826,14 +1865,14 @@ bool PipelineHandlerMaliC55::match(DeviceEnumerator *enumerator) * The TPG and the downscale pipe are both optional blocks and may not * be fitted. */ - DeviceMatch dm("mali-c55"); - dm.add("mali-c55 isp"); - dm.add("mali-c55 resizer fr"); - dm.add("mali-c55 fr"); - dm.add("mali-c55 3a stats"); - dm.add("mali-c55 3a params"); - - media_ = acquireMediaDevice(enumerator, dm); + DeviceMatch c55_dm("mali-c55"); + c55_dm.add("mali-c55 isp"); + c55_dm.add("mali-c55 resizer fr"); + c55_dm.add("mali-c55 fr"); + c55_dm.add("mali-c55 3a stats"); + c55_dm.add("mali-c55 3a params"); + + media_ = acquireMediaDevice(enumerator, c55_dm); if (!media_) return false; @@ -1893,6 +1932,22 @@ bool PipelineHandlerMaliC55::match(DeviceEnumerator *enumerator) stats_->bufferReady.connect(this, &PipelineHandlerMaliC55::statsBufferReady); params_->bufferReady.connect(this, &PipelineHandlerMaliC55::paramsBufferReady); + /* + * We also need to search for the rzg2l-cru CSI-2 receiver. If we find + * that then we need to work in memory input mode instead of the inline + * mode. The absence of this match is not necessarily a failure at this + * point...it depends on the media links that we investigate momentarily. + * + * This is a bit hacky, because there could be multiple of these media + * devices and we're just taking the first. We need modular pipelines to + * properly solve the issue. + */ + DeviceMatch cru_dm("rzg2l_cru"); + cru_dm.add(std::regex("csi-[0-9a-f]{8}.csi2")); + cru_dm.add(std::regex("cru-ip-[0-9a-f]{8}.cru[0-9]")); + cru_dm.add("CRU output"); + cruMedia_ = acquireMediaDevice(enumerator, cru_dm); + ispSink = isp_->entity()->getPadByIndex(0); if (!ispSink || ispSink->links().empty()) { LOG(MaliC55, Error) << "ISP sink pad error"; @@ -1907,12 +1962,13 @@ bool PipelineHandlerMaliC55::match(DeviceEnumerator *enumerator) * MEDIA_ENT_F_VID_IF_BRIDGE - A CSI-2 receiver * MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER - An input device * - * The last one will be unsupported for now. The TPG is relatively easy, - * we just register a Camera for it. If we have a CSI-2 receiver we need - * to check its sink pad and register Cameras for anything connected to - * it (probably...there are some complex situations in which that might - * not be true but let's pretend they don't exist until we come across - * them) + * The TPG is relatively easy, we just register a Camera for it. If we + * have a CSI-2 receiver we need to check its sink pad and register + * Cameras for anything connected to it (probably...there are some + * complex situations in which that might not be true but let's pretend + * they don't exist until we come across them). If we have an input + * device then we need to acquire the V4L2 infrastructure for it and + * confirm that we found the rzg2l-cru media device too. */ bool registered; for (MediaLink *link : ispSink->links()) { @@ -1932,7 +1988,21 @@ bool PipelineHandlerMaliC55::match(DeviceEnumerator *enumerator) break; case MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER: - LOG(MaliC55, Warning) << "Memory input not yet supported"; + if (!cruMedia_) + return false; + + ivc_ = V4L2Subdevice::fromEntityName(media_, "rzv2h ivc block"); + if (ivc_->open() < 0) + return false; + + input_ = V4L2VideoDevice::fromEntityName(media_, "rzv2h-ivc"); + if (input_->open() < 0) + return false; + + registered = registerMemoryInputCamera(); + if (!registered) + return registered; + break; default: LOG(MaliC55, Error) << "Unsupported entity function";