[libcamera-devel,3/9] libcamera: camera: Add camera ID

Message ID 20200718132324.867815-4-niklas.soderlund@ragnatech.se
State Superseded
Delegated to: Niklas Söderlund
Headers show
Series
  • libcamera: camera: Add camera ID
Related show

Commit Message

Niklas Söderlund July 18, 2020, 1:23 p.m. UTC
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(-)

Patch

diff --git a/include/libcamera/camera.h b/include/libcamera/camera.h
index 4d1a4a9f52ec0fac..132225a37dcd1ef4 100644
--- a/include/libcamera/camera.h
+++ b/include/libcamera/camera.h
@@ -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;
diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp
index 69a1b4428e3f4eca..638d15e0da5e1ca9 100644
--- a/src/libcamera/camera.cpp
+++ b/src/libcamera/camera.cpp
@@ -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))
 {
 }
 
diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp
index eb00eecfd10a89e4..09bab78b999b8b52 100644
--- a/src/libcamera/pipeline/ipu3/ipu3.cpp
+++ b/src/libcamera/pipeline/ipu3/ipu3.cpp
@@ -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);
 
diff --git a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp
index bf1c77144f855df9..487dc819daa1d0ec 100644
--- a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp
+++ b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp
@@ -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;
diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp
index 52a0d862417cc4ec..6f3699fe1a53eeaf 100644
--- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp
+++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp
@@ -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;
diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp
index 28d367883323d855..3c27cc28f672e020 100644
--- a/src/libcamera/pipeline/simple/simple.cpp
+++ b/src/libcamera/pipeline/simple/simple.cpp
@@ -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));
 	}
diff --git a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp
index 47f383d1551d5193..4484b70c6ec5f0ca 100644
--- a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp
+++ b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp
@@ -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. */
diff --git a/src/libcamera/pipeline/vimc/vimc.cpp b/src/libcamera/pipeline/vimc/vimc.cpp
index 4f461b928514022d..38656d28b357dd1b 100644
--- a/src/libcamera/pipeline/vimc/vimc.cpp
+++ b/src/libcamera/pipeline/vimc/vimc.cpp
@@ -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;