From patchwork Wed Mar 26 08:47:58 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Elder X-Patchwork-Id: 23033 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 AB5FCC323E for ; Wed, 26 Mar 2025 08:48:14 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 511376895D; Wed, 26 Mar 2025 09:48:14 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="Tfz4eUvt"; 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 1D90F6894B for ; Wed, 26 Mar 2025 09:48:11 +0100 (CET) Received: from neptunite.flets-east.jp (unknown [IPv6:2404:7a81:160:2100:7402:917d:ea0c:6d4c]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 399FD99F; Wed, 26 Mar 2025 09:46:21 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1742978783; bh=DesQDtS8FHV2a9taqydsAbbCEbQnkOwFxix2KOxgJ3w=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Tfz4eUvtUEkeDjiIJ8pHEn+NrgPnwA58xP7J0sdSN6wQXfCDUDLTLg5lC0lGKkXYV 3AuAP/QKo8XhwZO20G8ZtjUvcNfpEDFDsafFjR9ALJ7IWz4Cqv3mbua6rO0p10Pmqt /YFKgptAEhkNqAao54fOJSjpYrRfiuiraV0fmv70= From: Paul Elder To: libcamera-devel@lists.libcamera.org Cc: Paul Elder Subject: [PATCH v2 1/2] libcamera: pipeline: Add function to clear acquired media devices Date: Wed, 26 Mar 2025 17:47:58 +0900 Message-ID: <20250326084800.1880530-2-paul.elder@ideasonboard.com> X-Mailer: git-send-email 2.47.2 In-Reply-To: <20250326084800.1880530-1-paul.elder@ideasonboard.com> References: <20250326084800.1880530-1-paul.elder@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" Some pipeline handler implementations, such as the simple pipeline handler, can encounter systems with multiple media devices that can be supported. In a subsequent patch, the simple pipeline handler will be updated so that it will continue to match other media graphs even if the first media graph it encounters has an invalid media device. In this case, there would be a mix of invalid and valid media devices in mediaDevices_. Add a function to clear mediaDevices_ so that this can be prevented. Signed-off-by: Paul Elder --- New in v2 --- include/libcamera/internal/pipeline_handler.h | 2 ++ src/libcamera/pipeline_handler.cpp | 15 +++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/include/libcamera/internal/pipeline_handler.h b/include/libcamera/internal/pipeline_handler.h index 972a2fa65310..5fa8bc2f66ee 100644 --- a/include/libcamera/internal/pipeline_handler.h +++ b/include/libcamera/internal/pipeline_handler.h @@ -71,6 +71,8 @@ public: CameraManager *cameraManager() const { return manager_; } protected: + void clearMediaDevices(); + void registerCamera(std::shared_ptr camera); void hotplugMediaDevice(MediaDevice *media); diff --git a/src/libcamera/pipeline_handler.cpp b/src/libcamera/pipeline_handler.cpp index d84dff3c9f19..8f12957b75fa 100644 --- a/src/libcamera/pipeline_handler.cpp +++ b/src/libcamera/pipeline_handler.cpp @@ -142,6 +142,21 @@ MediaDevice *PipelineHandler::acquireMediaDevice(DeviceEnumerator *enumerator, return media.get(); } +/** + * \brief Clear the list of acquired media devices for this PipelineHandler instance + * + * This is meant to be used when the Pipeline Handler needs to search multiple + * media graphs to create multiple instances of itself, and a partial match + * needs to be canceled as an invalid media device was detected. This is to + * prevent mediaDevices_ from having a mix of invalid media devices from a + * previous failed match and valid media devices from the current succeeding + * match. + */ +void PipelineHandler::clearMediaDevices() +{ + mediaDevices_.clear(); +} + /** * \brief Acquire exclusive access to the pipeline handler for the process * From patchwork Wed Mar 26 08:47:59 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Elder X-Patchwork-Id: 23034 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 48BCDC323E for ; Wed, 26 Mar 2025 08:48:16 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 070366895E; Wed, 26 Mar 2025 09:48:16 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="HU6zDp6J"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id CA5C768947 for ; Wed, 26 Mar 2025 09:48:12 +0100 (CET) Received: from neptunite.flets-east.jp (unknown [IPv6:2404:7a81:160:2100:7402:917d:ea0c:6d4c]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id DC6D4475; Wed, 26 Mar 2025 09:46:23 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1742978785; bh=cbVTajNwRb0xuy1nyFHbxZqlZ3YPJDlLnVXTWvh3sJM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=HU6zDp6JTznC8JNLdY2/ISQL4CwM/Ayc2ltsOqoFQ7cn476452Hw2ieUTEzaSZpdG V3ofXtciYY2gGHnHKIOvENW29I0I6sLVE9XwB9og2zZAbhE0Aqa8VVP0LQLysTHIIS KKbzt1kxFO2f2aGyefpbyZ6dKCfloWG2ah6zkGWQ= From: Paul Elder To: libcamera-devel@lists.libcamera.org Cc: Paul Elder , Kieran Bingham Subject: [PATCH v2 2/2] pipeline: simple: Fix matching with empty media graphs Date: Wed, 26 Mar 2025 17:47:59 +0900 Message-ID: <20250326084800.1880530-3-paul.elder@ideasonboard.com> X-Mailer: git-send-email 2.47.2 In-Reply-To: <20250326084800.1880530-1-paul.elder@ideasonboard.com> References: <20250326084800.1880530-1-paul.elder@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 match() function currently reports that it is not possible to create any cameras if it encounters an empty media graph. Fix this by looping over all media graphs and only returning false when all of them fail to create a camera. Signed-off-by: Paul Elder Signed-off-by: Kieran Bingham --- Changes in v2: - prevent a mix of valid and invalid media devices from ending up in mediaDevices_ --- src/libcamera/pipeline/simple/simple.cpp | 52 ++++++++++++++++-------- 1 file changed, 35 insertions(+), 17 deletions(-) diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp index 6e039bf35fc1..a6bdd6024a99 100644 --- a/src/libcamera/pipeline/simple/simple.cpp +++ b/src/libcamera/pipeline/simple/simple.cpp @@ -373,6 +373,9 @@ private: return static_cast(camera->_d()); } + bool matchDevice(MediaDevice *media, const SimplePipelineInfo &info, + DeviceEnumerator *enumerator); + std::vector locateSensors(MediaDevice *media); static int resetRoutingTable(V4L2Subdevice *subdev); @@ -1532,25 +1535,13 @@ int SimplePipelineHandler::resetRoutingTable(V4L2Subdevice *subdev) return 0; } -bool SimplePipelineHandler::match(DeviceEnumerator *enumerator) +bool SimplePipelineHandler::matchDevice(MediaDevice *media, + const SimplePipelineInfo &info, + DeviceEnumerator *enumerator) { - const SimplePipelineInfo *info = nullptr; unsigned int numStreams = 1; - MediaDevice *media; - - for (const SimplePipelineInfo &inf : supportedDevices) { - DeviceMatch dm(inf.driver); - media = acquireMediaDevice(enumerator, dm); - if (media) { - info = &inf; - break; - } - } - - if (!media) - return false; - for (const auto &[name, streams] : info->converters) { + for (const auto &[name, streams] : info.converters) { DeviceMatch converterMatch(name); converter_ = acquireMediaDevice(enumerator, converterMatch); if (converter_) { @@ -1559,7 +1550,7 @@ bool SimplePipelineHandler::match(DeviceEnumerator *enumerator) } } - swIspEnabled_ = info->swIspEnabled; + swIspEnabled_ = info.swIspEnabled; /* Locate the sensors. */ std::vector sensors = locateSensors(media); @@ -1678,6 +1669,33 @@ bool SimplePipelineHandler::match(DeviceEnumerator *enumerator) return registered; } +bool SimplePipelineHandler::match(DeviceEnumerator *enumerator) +{ + MediaDevice *media; + + for (const SimplePipelineInfo &inf : supportedDevices) { + DeviceMatch dm(inf.driver); + while ((media = acquireMediaDevice(enumerator, dm))) { + /* + * If match succeeds, return true to let match() be + * called again on a new instance of the pipeline + * handler. Otherwise keep looping until we do + * successfully match one (or run out). + */ + if (matchDevice(media, inf, enumerator)) { + LOG(SimplePipeline, Debug) + << "Matched on device: " + << media->deviceNode(); + return true; + } + } + + clearMediaDevices(); + } + + return false; +} + V4L2VideoDevice *SimplePipelineHandler::video(const MediaEntity *entity) { auto iter = entities_.find(entity);