[RFC,01/12] libcamera: Infrastructure to ask for "memory" cameras
diff mbox series

Message ID 20250827090739.86955-2-david.plowman@raspberrypi.com
State New
Headers show
Series
  • Bayer Re-Processing
Related show

Commit Message

David Plowman Aug. 27, 2025, 9:07 a.m. UTC
Signed-off-by: David Plowman <david.plowman@raspberrypi.com>
---
 include/libcamera/camera_manager.h            |  4 ++
 include/libcamera/internal/camera_manager.h   |  5 +++
 include/libcamera/internal/pipeline_handler.h |  8 ++++
 src/libcamera/camera_manager.cpp              | 40 +++++++++++++++++++
 4 files changed, 57 insertions(+)

Patch
diff mbox series

diff --git a/include/libcamera/camera_manager.h b/include/libcamera/camera_manager.h
index 27835500..436db409 100644
--- a/include/libcamera/camera_manager.h
+++ b/include/libcamera/camera_manager.h
@@ -7,6 +7,7 @@ 
 
 #pragma once
 
+#include <map>
 #include <memory>
 #include <string>
 #include <string_view>
@@ -20,6 +21,7 @@ 
 namespace libcamera {
 
 class Camera;
+class PipelineHandler;
 
 class CameraManager : public Object, public Extensible
 {
@@ -33,6 +35,8 @@  public:
 
 	std::vector<std::shared_ptr<Camera>> cameras() const;
 	std::shared_ptr<Camera> get(std::string_view id);
+	std::vector<std::string> memoryCameras() const;
+	std::shared_ptr<Camera> getMemoryCamera(std::string_view id, std::string_view settings);
 
 	static const std::string &version() { return version_; }
 
diff --git a/include/libcamera/internal/camera_manager.h b/include/libcamera/internal/camera_manager.h
index 0150ca61..a490cb25 100644
--- a/include/libcamera/internal/camera_manager.h
+++ b/include/libcamera/internal/camera_manager.h
@@ -49,6 +49,9 @@  private:
 	void pipelineFactoryMatch(const PipelineHandlerFactoryBase *factory);
 	void cleanup() LIBCAMERA_TSA_EXCLUDES(mutex_);
 
+	std::shared_ptr<Camera> getMemoryCamera(const PipelineHandlerFactoryBase *factory,
+						std::string_view settings);
+
 	/*
 	 * This mutex protects
 	 *
@@ -64,6 +67,8 @@  private:
 
 	std::unique_ptr<DeviceEnumerator> enumerator_;
 
+	std::vector<std::string> memoryCameras_;
+
 	std::unique_ptr<IPAManager> ipaManager_;
 	ProcessManager processManager_;
 };
diff --git a/include/libcamera/internal/pipeline_handler.h b/include/libcamera/internal/pipeline_handler.h
index e89d6a33..0210d48b 100644
--- a/include/libcamera/internal/pipeline_handler.h
+++ b/include/libcamera/internal/pipeline_handler.h
@@ -70,6 +70,14 @@  public:
 
 	CameraManager *cameraManager() const { return manager_; }
 
+	virtual bool supportsMemoryCamera() { return false; }
+
+	virtual std::shared_ptr<Camera> createMemoryCamera([[maybe_unused]] DeviceEnumerator *enumerator,
+							   [[maybe_unused]] std::string_view settings)
+	{
+		return nullptr;
+	}
+
 protected:
 	void registerCamera(std::shared_ptr<Camera> camera);
 	void hotplugMediaDevice(MediaDevice *media);
diff --git a/src/libcamera/camera_manager.cpp b/src/libcamera/camera_manager.cpp
index f81794bf..580c31bf 100644
--- a/src/libcamera/camera_manager.cpp
+++ b/src/libcamera/camera_manager.cpp
@@ -152,6 +152,13 @@  void CameraManager::Private::pipelineFactoryMatch(const PipelineHandlerFactoryBa
 {
 	CameraManager *const o = LIBCAMERA_O_PTR();
 
+	/* First check for any memory-to-memory camera pipelines. */
+	{
+		std::shared_ptr<PipelineHandler> pipe = factory->create(o);
+		if (pipe->supportsMemoryCamera())
+			memoryCameras_.push_back(std::string(pipe->name()));
+	}
+
 	/* Provide as many matching pipelines as possible. */
 	while (1) {
 		std::shared_ptr<PipelineHandler> pipe = factory->create(o);
@@ -164,6 +171,19 @@  void CameraManager::Private::pipelineFactoryMatch(const PipelineHandlerFactoryBa
 	}
 }
 
+std::shared_ptr<Camera> CameraManager::Private::getMemoryCamera(const PipelineHandlerFactoryBase *factory,
+								std::string_view settings)
+{
+	CameraManager *const o = LIBCAMERA_O_PTR();
+
+	std::shared_ptr<PipelineHandler> pipe = factory->create(o);
+
+	pipe->moveToThread(this);
+
+	return pipe->invokeMethod(&PipelineHandler::createMemoryCamera,
+				  ConnectionTypeBlocking, enumerator_.get(), settings);
+}
+
 void CameraManager::Private::cleanup()
 {
 	enumerator_->devicesAdded.disconnect(this);
@@ -399,6 +419,26 @@  std::shared_ptr<Camera> CameraManager::get(std::string_view id)
 	return nullptr;
 }
 
+std::vector<std::string> CameraManager::memoryCameras() const
+{
+	return _d()->memoryCameras_;
+}
+
+std::shared_ptr<Camera> CameraManager::getMemoryCamera(std::string_view id,
+						       std::string_view settings)
+{
+	for (const auto &name : _d()->memoryCameras_) {
+		if (name == id) {
+			const PipelineHandlerFactoryBase *factory;
+			factory = PipelineHandlerFactoryBase::getFactoryByName(name);
+
+			return _d()->getMemoryCamera(factory, settings);
+		}
+	}
+
+	return nullptr;
+}
+
 /**
  * \var CameraManager::cameraAdded
  * \brief Notify of a new camera added to the system