summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/libcamera/camera_manager.h6
-rw-r--r--src/libcamera/camera_manager.cpp61
-rw-r--r--src/libcamera/include/pipeline_handler.h3
-rw-r--r--src/libcamera/pipeline_handler.cpp13
4 files changed, 69 insertions, 14 deletions
diff --git a/include/libcamera/camera_manager.h b/include/libcamera/camera_manager.h
index 8331898c..09419766 100644
--- a/include/libcamera/camera_manager.h
+++ b/include/libcamera/camera_manager.h
@@ -7,8 +7,10 @@
#ifndef __LIBCAMERA_CAMERA_MANAGER_H__
#define __LIBCAMERA_CAMERA_MANAGER_H__
+#include <map>
#include <memory>
#include <string>
+#include <sys/types.h>
#include <vector>
#include <libcamera/object.h>
@@ -33,8 +35,9 @@ public:
const std::vector<std::shared_ptr<Camera>> &cameras() const { return cameras_; }
std::shared_ptr<Camera> get(const std::string &name);
+ std::shared_ptr<Camera> get(dev_t devnum);
- void addCamera(std::shared_ptr<Camera> camera);
+ void addCamera(std::shared_ptr<Camera> camera, dev_t devnum);
void removeCamera(Camera *camera);
static const std::string &version() { return version_; }
@@ -46,6 +49,7 @@ private:
std::unique_ptr<DeviceEnumerator> enumerator_;
std::vector<std::shared_ptr<PipelineHandler>> pipes_;
std::vector<std::shared_ptr<Camera>> cameras_;
+ std::map<dev_t, std::weak_ptr<Camera>> camerasByDevnum_;
static const std::string version_;
static CameraManager *self_;
diff --git a/src/libcamera/camera_manager.cpp b/src/libcamera/camera_manager.cpp
index 7c6f72bb..a71caf85 100644
--- a/src/libcamera/camera_manager.cpp
+++ b/src/libcamera/camera_manager.cpp
@@ -181,14 +181,41 @@ std::shared_ptr<Camera> CameraManager::get(const std::string &name)
}
/**
+ * \brief Retrieve a camera based on device number
+ * \param[in] devnum Device number of camera to get
+ *
+ * This method is meant solely for the use of the V4L2 compatibility
+ * layer, to map device nodes to Camera instances. Applications shall
+ * not use it and shall instead retrieve cameras by name.
+ *
+ * Before calling this function the caller is responsible for ensuring that
+ * the camera manager is running.
+ *
+ * \return Shared pointer to Camera object, which is empty if the camera is
+ * not found
+ */
+std::shared_ptr<Camera> CameraManager::get(dev_t devnum)
+{
+ auto iter = camerasByDevnum_.find(devnum);
+ if (iter == camerasByDevnum_.end())
+ return nullptr;
+
+ return iter->second.lock();
+}
+
+/**
* \brief Add a camera to the camera manager
* \param[in] camera The camera to be added
+ * \param[in] devnum The device number to associate with \a camera
*
* This function is called by pipeline handlers to register the cameras they
* handle with the camera manager. Registered cameras are immediately made
* available to the system.
+ *
+ * \a devnum is used by the V4L2 compatibility layer to map V4L2 device nodes
+ * to Camera instances.
*/
-void CameraManager::addCamera(std::shared_ptr<Camera> camera)
+void CameraManager::addCamera(std::shared_ptr<Camera> camera, dev_t devnum)
{
for (std::shared_ptr<Camera> c : cameras_) {
if (c->name() == camera->name()) {
@@ -200,6 +227,11 @@ void CameraManager::addCamera(std::shared_ptr<Camera> camera)
}
cameras_.push_back(std::move(camera));
+
+ if (devnum) {
+ unsigned int index = cameras_.size() - 1;
+ camerasByDevnum_[devnum] = cameras_[index];
+ }
}
/**
@@ -212,15 +244,24 @@ void CameraManager::addCamera(std::shared_ptr<Camera> camera)
*/
void CameraManager::removeCamera(Camera *camera)
{
- for (auto iter = cameras_.begin(); iter != cameras_.end(); ++iter) {
- if (iter->get() == camera) {
- LOG(Camera, Debug)
- << "Unregistering camera '"
- << camera->name() << "'";
- cameras_.erase(iter);
- return;
- }
- }
+ auto iter = std::find_if(cameras_.begin(), cameras_.end(),
+ [camera](std::shared_ptr<Camera> &c) {
+ return c.get() == camera;
+ });
+ if (iter == cameras_.end())
+ return;
+
+ LOG(Camera, Debug)
+ << "Unregistering camera '" << camera->name() << "'";
+
+ auto iter_d = std::find_if(camerasByDevnum_.begin(), camerasByDevnum_.end(),
+ [camera](const std::pair<dev_t, std::weak_ptr<Camera>> &p) {
+ return p.second.lock().get() == camera;
+ });
+ if (iter_d != camerasByDevnum_.end())
+ camerasByDevnum_.erase(iter_d);
+
+ cameras_.erase(iter);
}
/**
diff --git a/src/libcamera/include/pipeline_handler.h b/src/libcamera/include/pipeline_handler.h
index f3622631..067baef5 100644
--- a/src/libcamera/include/pipeline_handler.h
+++ b/src/libcamera/include/pipeline_handler.h
@@ -12,6 +12,7 @@
#include <memory>
#include <set>
#include <string>
+#include <sys/sysmacros.h>
#include <vector>
#include <ipa/ipa_interface.h>
@@ -86,7 +87,7 @@ public:
protected:
void registerCamera(std::shared_ptr<Camera> camera,
- std::unique_ptr<CameraData> data);
+ std::unique_ptr<CameraData> data, dev_t devnum = 0);
void hotplugMediaDevice(MediaDevice *media);
virtual int queueRequestDevice(Camera *camera, Request *request) = 0;
diff --git a/src/libcamera/pipeline_handler.cpp b/src/libcamera/pipeline_handler.cpp
index 5badf31c..698dd525 100644
--- a/src/libcamera/pipeline_handler.cpp
+++ b/src/libcamera/pipeline_handler.cpp
@@ -7,6 +7,8 @@
#include "pipeline_handler.h"
+#include <sys/sysmacros.h>
+
#include <libcamera/buffer.h>
#include <libcamera/camera.h>
#include <libcamera/camera_manager.h>
@@ -438,19 +440,26 @@ void PipelineHandler::completeRequest(Camera *camera, Request *request)
* \brief Register a camera to the camera manager and pipeline handler
* \param[in] camera The camera to be added
* \param[in] data Pipeline-specific data for the camera
+ * \param[in] devnum Device number of the camera (optional)
*
* This method is called by pipeline handlers to register the cameras they
* handle with the camera manager. It associates the pipeline-specific \a data
* with the camera, for later retrieval with cameraData(). Ownership of \a data
* is transferred to the PipelineHandler.
+ *
+ * \a devnum is the device number (as returned by makedev) that the \a camera
+ * is to be associated with. This is for the V4L2 compatibility layer to map
+ * device nodes to Camera instances based on the device number
+ * registered by this method in \a devnum.
*/
void PipelineHandler::registerCamera(std::shared_ptr<Camera> camera,
- std::unique_ptr<CameraData> data)
+ std::unique_ptr<CameraData> data,
+ dev_t devnum)
{
data->camera_ = camera.get();
cameraData_[camera.get()] = std::move(data);
cameras_.push_back(camera);
- manager_->addCamera(std::move(camera));
+ manager_->addCamera(std::move(camera), devnum);
}
/**