@@ -70,12 +70,14 @@ class Camera final : public std::enable_shared_from_this<Camera>
{
public:
static std::shared_ptr<Camera> create(PipelineHandler *pipe,
+ const std::string &id,
const std::string &name,
const std::set<Stream *> &streams);
Camera(const Camera &) = delete;
Camera &operator=(const Camera &) = delete;
+ const std::string &id() const;
const std::string &name() const;
Signal<Request *, FrameBuffer *> bufferCompleted;
@@ -99,8 +101,8 @@ public:
int stop();
private:
- Camera(PipelineHandler *pipe, const std::string &name,
- const std::set<Stream *> &streams);
+ Camera(PipelineHandler *pipe, const std::string &id,
+ const std::string &name, const std::set<Stream *> &streams);
~Camera();
class Private;
@@ -265,8 +265,8 @@ public:
CameraRunning,
};
- Private(PipelineHandler *pipe, const std::string &name,
- const std::set<Stream *> &streams);
+ Private(PipelineHandler *pipe, const std::string &id,
+ const std::string &name, const std::set<Stream *> &streams);
~Private();
int isAccessAllowed(State state, bool allowDisconnected = false) const;
@@ -277,6 +277,7 @@ public:
void setState(State state);
std::shared_ptr<PipelineHandler> pipe_;
+ std::string id_;
std::string name_;
std::set<Stream *> streams_;
std::set<Stream *> activeStreams_;
@@ -286,10 +287,11 @@ private:
std::atomic<State> state_;
};
-Camera::Private::Private(PipelineHandler *pipe, const std::string &name,
+Camera::Private::Private(PipelineHandler *pipe, const std::string &id,
+ const std::string &name,
const std::set<Stream *> &streams)
- : pipe_(pipe->shared_from_this()), name_(name), streams_(streams),
- disconnected_(false), state_(CameraAvailable)
+ : pipe_(pipe->shared_from_this()), id_(id), name_(name),
+ streams_(streams), disconnected_(false), state_(CameraAvailable)
{
}
@@ -450,14 +452,16 @@ void Camera::Private::setState(State state)
/**
* \brief Create a camera instance
* \param[in] pipe The pipeline handler responsible for the camera device
+ * \param[in] id The ID of the camera device
* \param[in] name The name of the camera device
* \param[in] streams Array of streams the camera provides
*
- * The caller is responsible for guaranteeing unicity of the camera name.
+ * The caller is responsible for guaranteeing unicity of the camera ID.
*
* \return A shared pointer to the newly created camera object
*/
std::shared_ptr<Camera> Camera::create(PipelineHandler *pipe,
+ const std::string &id,
const std::string &name,
const std::set<Stream *> &streams)
{
@@ -468,7 +472,7 @@ std::shared_ptr<Camera> Camera::create(PipelineHandler *pipe,
}
};
- Camera *camera = new Camera(pipe, name, streams);
+ Camera *camera = new Camera(pipe, id, name, streams);
return std::shared_ptr<Camera>(camera, Deleter());
}
@@ -483,6 +487,16 @@ const std::string &Camera::name() const
return p_->name_;
}
+/**
+ * \brief Retrieve the camera ID
+ * \context This function is \threadsafe.
+ * \return Unique ID of the camera device
+ */
+const std::string &Camera::id() const
+{
+ return p_->id_;
+}
+
/**
* \var Camera::bufferCompleted
* \brief Signal emitted when a buffer for a request queued to the camera has
@@ -506,9 +520,9 @@ const std::string &Camera::name() const
* application API calls by returning errors immediately.
*/
-Camera::Camera(PipelineHandler *pipe, const std::string &name,
- const std::set<Stream *> &streams)
- : p_(new Private(pipe, name, streams))
+Camera::Camera(PipelineHandler *pipe, const std::string &id,
+ const std::string &name, const std::set<Stream *> &streams)
+ : p_(new Private(pipe, id, name, streams))
{
}
@@ -815,6 +815,7 @@ int PipelineHandlerIPU3::registerCameras()
/* Create and register the Camera instance. */
std::string cameraName = cio2->sensor()->entity()->name();
std::shared_ptr<Camera> camera = Camera::create(this,
+ cio2->sensor()->id(),
cameraName,
streams);
@@ -973,7 +973,10 @@ bool PipelineHandlerRPi::match(DeviceEnumerator *enumerator)
streams.insert(&data->isp_[Isp::Stats]);
/* Create and register the camera. */
- std::shared_ptr<Camera> camera = Camera::create(this, data->sensor_->model(), streams);
+ std::shared_ptr<Camera> camera = Camera::create(this,
+ data->sensor_->id(),
+ data->sensor_->model(),
+ streams);
registerCamera(std::move(camera), std::move(data));
return true;
@@ -971,7 +971,8 @@ int PipelineHandlerRkISP1::createCamera(MediaEntity *sensor)
std::set<Stream *> streams{ &data->stream_ };
std::shared_ptr<Camera> camera =
- Camera::create(this, sensor->name(), streams);
+ Camera::create(this, data->sensor_->id(), sensor->name(),
+ streams);
registerCamera(std::move(camera), std::move(data));
return 0;
@@ -800,7 +800,8 @@ bool SimplePipelineHandler::match(DeviceEnumerator *enumerator)
continue;
std::shared_ptr<Camera> camera =
- Camera::create(this, data->sensor_->entity()->name(),
+ Camera::create(this, data->sensor_->id(),
+ data->sensor_->entity()->name(),
data->streams());
registerCamera(std::move(camera), std::move(data));
}
@@ -406,8 +406,13 @@ bool PipelineHandlerUVC::match(DeviceEnumerator *enumerator)
return false;
/* Create and register the camera. */
+ std::string id = data->video_->devicePath();
+ const std::string dropStr = "/sys/devices/";
+ if (id.find(dropStr) == 0)
+ id.erase(0, dropStr.length());
+
std::set<Stream *> streams{ &data->stream_ };
- std::shared_ptr<Camera> camera = Camera::create(this, media->model(), streams);
+ std::shared_ptr<Camera> camera = Camera::create(this, id, media->model(), streams);
registerCamera(std::move(camera), std::move(data));
/* Enable hot-unplug notifications. */
@@ -434,7 +434,8 @@ bool PipelineHandlerVimc::match(DeviceEnumerator *enumerator)
/* Create and register the camera. */
std::string name{ "VIMC " + data->sensor_->model() };
std::set<Stream *> streams{ &data->stream_ };
- std::shared_ptr<Camera> camera = Camera::create(this, name, streams);
+ std::shared_ptr<Camera> camera = Camera::create(this, data->sensor_->id(),
+ name, streams);
registerCamera(std::move(camera), std::move(data));
return true;
Add an ID when creating a camera. The ID is a free form string that must be unique for the camera in the system. The ID shall also be persistent between reboots. All but the UVC pipeline is modified to use the ID of the sensor of each camera. The ID of the sensor guarantees the properties required of the camera ID. The UVC pipeline does not have a sensor so instead creates a unique and persistent ID from the video device path which includes the USB bus information and thus satisfy the camera ID requirements. Future changes will make use of and enforce the uniqueness of camera IDs. Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> --- include/libcamera/camera.h | 6 ++-- src/libcamera/camera.cpp | 34 +++++++++++++------ src/libcamera/pipeline/ipu3/ipu3.cpp | 1 + .../pipeline/raspberrypi/raspberrypi.cpp | 5 ++- src/libcamera/pipeline/rkisp1/rkisp1.cpp | 3 +- src/libcamera/pipeline/simple/simple.cpp | 3 +- src/libcamera/pipeline/uvcvideo/uvcvideo.cpp | 7 +++- src/libcamera/pipeline/vimc/vimc.cpp | 3 +- 8 files changed, 45 insertions(+), 17 deletions(-)