[libcamera-devel] [PATCH v5 4/5] libcamera: pipeline: uvcvideo: Generate unique camera names

Niklas Söderlund niklas.soderlund at ragnatech.se
Wed Jul 29 13:50:54 CEST 2020


Generate camera names that are unique and persistent between system
resets. The name is constructed from the USB vendor and product
information that is stored on USB device itself and the USB bus and
device numbers where the hardware is plugged in.

Before this change example of camera names:

Venus USB2.0 Camera: Venus USB2
Logitech Webcam C930e

After this change the same cameras are:

0ac8:3420:3:10
046d:0843:3:4

Signed-off-by: Niklas Söderlund <niklas.soderlund at ragnatech.se>
Reviewed-by: Jacopo Mondi <jacopo at jmondi.org>
---
* Changes since v3
- Switch argument to generateName() to UVCCameraData pointer.
---
 src/libcamera/pipeline/uvcvideo/uvcvideo.cpp | 35 +++++++++++++++++++-
 1 file changed, 34 insertions(+), 1 deletion(-)

diff --git a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp
index 93e3dc17e3a7105e..f51529ea519f5aee 100644
--- a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp
+++ b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp
@@ -6,6 +6,7 @@
  */
 
 #include <algorithm>
+#include <fstream>
 #include <iomanip>
 #include <math.h>
 #include <tuple>
@@ -81,6 +82,8 @@ public:
 	bool match(DeviceEnumerator *enumerator) override;
 
 private:
+	std::string generateName(const UVCCameraData *data);
+
 	int processControl(ControlList *controls, unsigned int id,
 			   const ControlValue &value);
 	int processControls(UVCCameraData *data, Request *request);
@@ -379,6 +382,30 @@ int PipelineHandlerUVC::queueRequestDevice(Camera *camera, Request *request)
 	return 0;
 }
 
+std::string PipelineHandlerUVC::generateName(const UVCCameraData *data)
+{
+
+	static const std::vector<std::string> files
+		= { "idVendor", "idProduct", "busnum", "devnum" };
+	std::string path = data->video_->devicePath();
+	std::vector<std::string> values;
+	std::string value;
+
+	for (const std::string &name : files) {
+		std::ifstream file(path + "/../" + name);
+
+		if (!file.is_open())
+			return "";
+
+		std::getline(file, value);
+		file.close();
+
+		values.push_back(value);
+	}
+
+	return utils::join(values, ":");
+}
+
 bool PipelineHandlerUVC::match(DeviceEnumerator *enumerator)
 {
 	MediaDevice *media;
@@ -405,8 +432,14 @@ bool PipelineHandlerUVC::match(DeviceEnumerator *enumerator)
 		return false;
 
 	/* Create and register the camera. */
+	std::string name = generateName(data.get());
+	if (name.empty()) {
+		LOG(UVC, Error) << "Failed to generate camera name";
+		return false;
+	}
+
 	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, name, streams);
 	registerCamera(std::move(camera), std::move(data));
 
 	/* Enable hot-unplug notifications. */
-- 
2.27.0



More information about the libcamera-devel mailing list