From patchwork Fri Sep 18 07:59:44 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Naushir Patuck X-Patchwork-Id: 28318 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 52F16C3357 for ; Fri, 18 Sep 2026 08:07:52 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 35F406870A; Fri, 18 Sep 2026 10:07:49 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=raspberrypi.com header.i=@raspberrypi.com header.b="eHnMXKfH"; dkim-atps=neutral Received: from mail-wr2-x10.google.com (mail-wr2-x10.google.com [IPv6:2a00:1450:4864:30::10]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 385B46870F for ; Fri, 18 Sep 2026 10:07:44 +0200 (CEST) Received: by mail-wr2-x10.google.com with SMTP id ffacd0b85a97d-48435bcf9d9so56205f8f.1 for ; Fri, 18 Sep 2026 01:07:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=raspberrypi.com; s=google; t=1789718864; x=1790323664; 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=iV5drikcs2jU12OmeHjXo9iBFPd9LgBhoEPYV/Xjtqc=; b=eHnMXKfHVKpvMq3dfV4gTNJrbfAvcm8BVypWZ9aeyCdY8oIjWB79EWxit7fld8FRo4 1NKzGw5OT2hEPJn/rBZBwtKhwZVp/NEtiefA6TGSaN1Dm8pTVf6mo5/QpFjHJAa6EqND 6LiBqstScv++/hoCowifRrWKRl0starn2I4HZzMAIKNcntMC6xyBQh8iAy3pcdZPAfFz jMKucLWhol3yMiDcluySijQJGxNu/TZJvBrc7xtTWsuUvGSAZS5uwdAHr+U93DX6hLcf L5UYx9u2ZzTOyi0Wha8WWh5x1k7bJqcDiaaeN9Bd8t4MIDfZMvZC7zUHouwB7zTnbdfL z3pw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1789718864; x=1790323664; 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=iV5drikcs2jU12OmeHjXo9iBFPd9LgBhoEPYV/Xjtqc=; b=Y1USHX6twdtZ3lkuyHfzcDj0ltCSGa+eiUTfbVzGrnFItFp7w0iX+sz6fNsiib9PJY FsdwhgYF1IIuSlvimSzxeRsFh1quPVmq7NegNaTUDiBmL2Vz1lqPsc5ZTv0qZRZbL6Ee wHXBl95G9obTa8Y40Oq/lQ5PykADO9oHtj/N1yLRWRkL805Ura3dG+zDfZvaC01W9vav RqLW2Jwyh4rXSr1s9zCxOEkOh6V9U3r+CrCY6t5iGenzQ/XPjd8A8rZCEHR5vP34ZIOK qv1ynlOIUuZtl/uwY7icXBOG4dtQZJ6IfdeuXUGasecZucxvJ/qlY5VnIyyzqsxiiJb1 g5Ug== X-Gm-Message-State: AFuF++lOi174pQUAHjNHE2coFAL/yIo0tyJVZO8eR6R+TysaSG2GGbyj yVIZD3PjdCrxNSpiClf3rIeOCJjHEOhZ/UoB64tGnIrwvz3Ph6sFsGpzcKUHS0SvlJTrFb9iiaM mpar8RMs= X-Gm-Gg: AYBFou2cT+jpJ6sIw+s9zZPqcD3rEodvz1LMWMfQOu4MGIhCQ9qG+sURW4tvd+4P7EZ tzNglpWLrc1RWUCx3gJxn8PrZDXtyAosNZ4BB8e6mqh/jmh+RSbm3OoLf4lFwl7DMFz0YDvylhG diJMmsfqSevKIccgYAd+n9eeye6WC8muXnFdkZOI0muwr8upEGzvAIGZGy2k51uWJdhJgGbA5lh BVLSngWf5lDrpm7VhFOaxo0/Bcpsw6cTLbO/BLSRebusQBmMddigDkVxUfxtT5Qua8z7oBivCnx G5M0Ow6i1KFOyy/OvBEdEokoMNlTL+zvk7RPI998+kUmf9SkgQuvSKNn1FPuKZMfQSjj7j55THn sbhOiF9mEsm3BVH1c/e7oheX6Ume7bXCxF9vRA/jO1WPlpbIjxRzCup5fN5M7TdvjvA3QxP7Oa7 JoSoA2yCJSqPWziRYYEwyQxmLIiGSO+u3yd5vboHBVKNavlfLpdDB3OlgfCYli7gT0vFz2yPR8B 6X7EWpGXUyJ9A8JcrvF2N7FtdOKcg/0lV4fueGo9SBsT3uurW6f/ZYIi6dme/2JIr1LsKlXYuWz MzV94B1hEqPZXN0z6SCEdJHrsExelpRqFQVn6q+4wfmfbS1pHc7vLdvxzTEpqPVlLyIpi9Re884 KNeIIuZQJJy4XQ5qo+F5wuKdWlREVmigL/OB/lasiKAI33A== X-Received: by 2002:a05:6000:4283:b0:485:8df0:dca with SMTP id ffacd0b85a97d-4871fa7286dmr1456886f8f.3.1789718863574; Fri, 18 Sep 2026 01:07:43 -0700 (PDT) Received: from naush-dell.pitowers.org ([2a00:1098:3142:1f:45e3:df8b:2b18:6253]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-487203f077fsm1742230f8f.26.2026.09.18.01.07.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 18 Sep 2026 01:07:43 -0700 (PDT) From: Naushir Patuck To: libcamera-devel@lists.libcamera.org Cc: Naushir Patuck Subject: [RFC PATCH v1 06/20] libcamera: pipeline_handler: Add survey() and createCamera() Date: Fri, 18 Sep 2026 08:59:44 +0100 Message-ID: <20260918080734.1228227-7-naush@raspberrypi.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260918080734.1228227-1-naush@raspberrypi.com> References: <20260918080734.1228227-1-naush@raspberrypi.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 two virtual functions splitting the match() contract into a cheap enumeration half and a heavy per-camera initialisation half. survey() reports descriptors for the cameras a pipeline handler supports without acquiring media devices or altering hardware state. createCamera() initialises and registers a single camera from one of those descriptors. The base implementations report no descriptors and -ENOTSUP respectively, so pipeline handlers may keep using match() unchanged. Also add a usesMediaDevice() helper that the camera manager will use to route descriptors to pipeline handlers in a future commit. Signed-off-by: Naushir Patuck --- include/libcamera/internal/pipeline_handler.h | 5 ++ src/libcamera/pipeline_handler.cpp | 75 +++++++++++++++++++ 2 files changed, 80 insertions(+) diff --git a/include/libcamera/internal/pipeline_handler.h b/include/libcamera/internal/pipeline_handler.h index 6a018fe42866..c22c69e70fae 100644 --- a/include/libcamera/internal/pipeline_handler.h +++ b/include/libcamera/internal/pipeline_handler.h @@ -24,6 +24,7 @@ namespace libcamera { class Camera; class CameraConfiguration; +class CameraDescriptor; class DeviceEnumerator; class DeviceMatch; class FrameBuffer; @@ -40,8 +41,12 @@ public: virtual ~PipelineHandler(); virtual bool match(DeviceEnumerator *enumerator) = 0; + virtual int survey(const DeviceEnumerator *enumerator, + std::vector> *descriptors); + virtual int createCamera(const CameraDescriptor *descriptor); std::shared_ptr acquireMediaDevice(DeviceEnumerator *enumerator, const DeviceMatch &dm); + bool usesMediaDevice(const MediaDevice *media) const; bool acquire(Camera *camera); void release(Camera *camera); diff --git a/src/libcamera/pipeline_handler.cpp b/src/libcamera/pipeline_handler.cpp index a803f6208c32..30079fa9f665 100644 --- a/src/libcamera/pipeline_handler.cpp +++ b/src/libcamera/pipeline_handler.cpp @@ -115,6 +115,62 @@ PipelineHandler::~PipelineHandler() * created, or false otherwise */ +/** + * \brief Survey the media devices for cameras this pipeline handler supports + * \param[in] enumerator The enumerator providing all media devices found in the + * system + * \param[out] descriptors The vector to which the descriptors of the cameras + * found are appended + * + * This function inspects the media devices provided by the \a enumerator and + * produces a camera descriptor for every camera that this pipeline handler + * supports. It shall not acquire any media device, open any device node, or + * alter any hardware state. + * + * Unlike match(), a single call shall report the cameras of all matching + * pipeline instances in the system, in the same order as repeated match() calls + * would register them. + * + * Pipeline handlers that do not implement this function do not support camera + * enumeration through CameraManager::enumerate(), and their cameras are only + * created through match(). + * + * A pipeline handler that supports surveying shall return 0 and append a + * descriptor to \a descriptors for every camera it finds. Pipeline handlers + * that don't support surveying return -ENOTSUP from the default implementation. + * + * \context This function is called from the CameraManager thread. + * + * \return 0 on success or a negative error code otherwise + * \retval -ENOTSUP The pipeline handler does not support surveying + */ +int PipelineHandler::survey([[maybe_unused]] const DeviceEnumerator *enumerator, + [[maybe_unused]] std::vector> *descriptors) +{ + return -ENOTSUP; +} + +/** + * \brief Create and register the camera described by a descriptor + * \param[in] descriptor The descriptor of the camera to create + * + * This function performs the initialisation of a single camera previously + * reported by survey(). It shall acquire the media devices for the camera, + * unless this pipeline handler instance has already acquired them for a + * previously created camera, perform the same per-camera initialisation as + * match(), and register the camera with the camera manager. + * + * \context This function is called from the CameraManager thread. + * + * \return 0 on success or a negative error code otherwise + * \retval -ENOTSUP The pipeline handler does not support camera creation from + * a descriptor + */ +int PipelineHandler::createCamera([[maybe_unused]] const CameraDescriptor *descriptor) +{ + return -ENOTSUP; +} + /** * \brief Search and acquire a MediaDevice matching a device pattern * \param[in] enumerator Enumerator containing all media devices in the system @@ -148,6 +204,25 @@ PipelineHandler::acquireMediaDevice(DeviceEnumerator *enumerator, return media; } +/** + * \brief Check if this pipeline handler instance uses a media device + * \param[in] media The media device to check for + * + * \context This function shall be called from the CameraManager thread. + * + * \return True if \a media has been acquired by this pipeline handler + * instance, otherwise false + */ +bool PipelineHandler::usesMediaDevice(const MediaDevice *media) const +{ + for (const std::shared_ptr &m : mediaDevices_) { + if (m.get() == media) + return true; + } + + return false; +} + /** * \brief Acquire exclusive access to the pipeline handler for the process *