@@ -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_; }
@@ -55,6 +55,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
*
@@ -70,6 +73,8 @@ private:
std::unique_ptr<DeviceEnumerator> enumerator_;
+ std::vector<std::string> memoryCameras_;
+
std::unique_ptr<IPAManager> ipaManager_;
const GlobalConfiguration configuration_;
@@ -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(std::shared_ptr<MediaDevice> media);
@@ -155,6 +155,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);
@@ -167,6 +174,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);
@@ -371,6 +391,9 @@ void CameraManager::stop()
* Before calling this function the caller is responsible for ensuring that
* the camera manager is running.
*
+ * This function does not list any memory cameras (for processing raw images
+ * held in memory buffers) that may be available.
+ *
* \context This function is \threadsafe.
*
* \return List of all available cameras
@@ -409,6 +432,47 @@ std::shared_ptr<Camera> CameraManager::get(std::string_view id)
return nullptr;
}
+/**
+ * \brief List the pipeline handlers that support memory cameras
+ *
+ * Lists the pipeline handlers in the system that have indicated they
+ * support memory cameras. Memory cameras are used for processing raw
+ * camera images stored in memory buffers, where no corresponding
+ * camera is available.
+ *
+ * \return Vector of pipeline handler ids (strings)
+ */
+std::vector<std::string> CameraManager::memoryCameras() const
+{
+ return _d()->memoryCameras_;
+}
+
+/**
+ * \brief Get a memory camera from the named pipeline handler
+ * \param[in] id ID of the pipeline handler that should create the memory camera
+ *
+ * This function causes the named pipeline handler to create and return a
+ * memory camera to the application. Pipeline handlers may support multiple
+ * simultaneous memory cameras, or none at all.
+ *
+ * \return Shared pointer to Camera object or nullptr if no memory camera
+ * could be provided
+ */
+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
@@ -835,6 +835,29 @@ void PipelineHandler::disconnect()
* \return The CameraManager for this pipeline handler
*/
+/**
+ * \fn PipelineHandler::supportsMemoryCamera()
+ * \brief Indicate whether this pipeline handler supports memory cameras.
+ * \return True if the pipeline handler supports memory cameras, otherwise false.
+ */
+
+/**
+ * \fn PipelineHandler::createMemoryCamera()
+ * \brief Create a memory camera to process raw camera images from a memory buffer
+ * \param[in] enumerator The enumerator providing all media devices found in the
+ * system
+ * \param[in] settings A string of settings that the pipeline handler should use
+ *
+ * The pipeline handler should create a memory camera, which an application can
+ * use to process raw camera images that are stored in memory buffers (rather
+ * than being delivered from a live camera).
+ *
+ * The settings should indicate exactly what processing the application requires
+ * to be performed on the raw image.
+ *
+ * \return Shared pointer to a camera, or a nullptr if none could be created
+ */
+
/**
* \class PipelineHandlerFactoryBase
* \brief Base class for pipeline handler factories
"Memory" cameras are used to make it easier to process raw camera images that are stored in memory buffers. There may be no actual camera attached to the system at all. Memory cameras are not created when the system starts. Depending on the pipeline handler, it may be possible to open many memory cameras simultaneously, or none at all. So any time an application requests a memory camera, we check with the pipeline handler whether it can provide one. 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 | 64 +++++++++++++++++++ src/libcamera/pipeline_handler.cpp | 23 +++++++ 5 files changed, 104 insertions(+)