[RFC,v1,09/20] libcamera: camera_manager: Track active pipeline handler instances
diff mbox series

Message ID 20260918080734.1228227-10-naush@raspberrypi.com
State New
Headers show
Series
  • libcamera: New enumeration API
Related show

Commit Message

Naushir Patuck Sept. 18, 2026, 7:59 a.m. UTC
The camera manager drops its reference to a pipeline handler as soon as
match() returns, leaving the instance owned solely by the Camera object.

Store a vector of weak references to matched pipeline handler instances.
This will allow camera initialisation from a descriptor to link to an
existing pipeline handler instance rather than creating a second
instance for media devices that are already acquired. Weak references
leave the existing ownership and lifetime model unchanged.

Add a findMatchingHandler() helper that returns the active pipeline
handler instance that has acquired a given media device, pruning expired
references as it goes. This will be used in a future commit.

Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
---
 include/libcamera/internal/camera_manager.h |  9 +++++++
 src/libcamera/camera_manager.cpp            | 30 +++++++++++++++++++++
 2 files changed, 39 insertions(+)

Patch
diff mbox series

diff --git a/include/libcamera/internal/camera_manager.h b/include/libcamera/internal/camera_manager.h
index cfedee433857..89c8e4eda766 100644
--- a/include/libcamera/internal/camera_manager.h
+++ b/include/libcamera/internal/camera_manager.h
@@ -26,6 +26,8 @@  namespace libcamera {
 class Camera;
 class DeviceEnumerator;
 class IPAManager;
+class MediaDevice;
+class PipelineHandler;
 class PipelineHandlerFactoryBase;
 
 class CameraManager::Private : public Extensible::Private, public Thread
@@ -53,6 +55,7 @@  private:
 	int init();
 	void createPipelineHandlers();
 	void pipelineFactoryMatch(const PipelineHandlerFactoryBase *factory);
+	std::shared_ptr<PipelineHandler> findMatchingHandler(const MediaDevice *media);
 	void cleanup() LIBCAMERA_TSA_EXCLUDES(mutex_);
 
 	/*
@@ -70,6 +73,12 @@  private:
 
 	std::unique_ptr<DeviceEnumerator> enumerator_;
 
+	/*
+	 * Active pipeline handler instances, accessed from the CameraManager
+	 * thread only.
+	 */
+	std::vector<std::weak_ptr<PipelineHandler>> pipes_;
+
 	std::unique_ptr<IPAManager> ipaManager_;
 
 	const GlobalConfiguration configuration_;
diff --git a/src/libcamera/camera_manager.cpp b/src/libcamera/camera_manager.cpp
index 784ae012e280..bd9cc155b961 100644
--- a/src/libcamera/camera_manager.cpp
+++ b/src/libcamera/camera_manager.cpp
@@ -178,7 +178,37 @@  void CameraManager::Private::pipelineFactoryMatch(const PipelineHandlerFactoryBa
 		LOG(Camera, Debug)
 			<< "Pipeline handler \"" << factory->name()
 			<< "\" matched";
+
+		pipes_.push_back(pipe);
+	}
+}
+
+/*
+ * Find the active pipeline handler instance that has acquired the media device,
+ * if any. Expired entries are pruned from the registry as a side effect. Called
+ * from the CameraManager thread only.
+ */
+std::shared_ptr<PipelineHandler>
+CameraManager::Private::findMatchingHandler(const MediaDevice *media)
+{
+	ASSERT(Thread::current() == this);
+
+	std::shared_ptr<PipelineHandler> match;
+
+	for (auto it = pipes_.begin(); it != pipes_.end();) {
+		std::shared_ptr<PipelineHandler> pipe = it->lock();
+		if (!pipe) {
+			it = pipes_.erase(it);
+			continue;
+		}
+
+		if (!match && pipe->usesMediaDevice(media))
+			match = std::move(pipe);
+
+		++it;
 	}
+
+	return match;
 }
 
 void CameraManager::Private::cleanup()