[libcamera-devel,v2,5/6] libcamera: pipeline: uvcvideo: Generate unique camera names

Message ID 20200728003058.2871461-6-niklas.soderlund@ragnatech.se
State Superseded
Headers show
Series
  • libcamera: Generate unique and stable camera names
Related show

Commit Message

Niklas Söderlund July 28, 2020, 12:30 a.m. UTC
Generate camera names that contains enough information to be unique
while still being user friendly. In addition to the UVC model name add
information about which USB bus and device it is and if available the
serial number of the USB device.

Before this change example of camera names:

Venus USB2.0 Camera: Venus USB2 (PipelineHandlerUVC)
Logitech Webcam C930e (PipelineHandlerUVC)

After this change the same cameras are:

Venus USB2.0 Camera: Venus USB2 on bus 3:8 (PipelineHandlerUVC)
Logitech Webcam C930e on bus 3:4 serial 9F8F445E (PipelineHandlerUVC)

Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
---
 src/libcamera/pipeline/uvcvideo/uvcvideo.cpp | 41 +++++++++++++++++++-
 1 file changed, 40 insertions(+), 1 deletion(-)

Patch

diff --git a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp
index 93e3dc17e3a7105e..b415678b13e28f5d 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,9 @@  public:
 	bool match(DeviceEnumerator *enumerator) override;
 
 private:
+	std::string generateName(const MediaDevice *media,
+				 const std::string path);
+
 	int processControl(ControlList *controls, unsigned int id,
 			   const ControlValue &value);
 	int processControls(UVCCameraData *data, Request *request);
@@ -379,6 +383,35 @@  int PipelineHandlerUVC::queueRequestDevice(Camera *camera, Request *request)
 	return 0;
 }
 
+std::string PipelineHandlerUVC::generateName(const MediaDevice *media,
+					     const std::string path)
+{
+	std::string name, busnum, devnum;
+	std::ifstream file;
+
+	file.open(path + "/../busnum");
+	if (!file.is_open())
+		return "";
+	std::getline(file, busnum);
+	file.close();
+
+	file.open(path + "/../devnum");
+	if (!file.is_open())
+		return "";
+	std::getline(file, devnum);
+	file.close();
+
+	if (busnum.empty() || devnum.empty())
+		return "";
+
+	name = media->model() + " on bus " + busnum + ":" + devnum;
+
+	if (!media->serial().empty())
+		name += " serial " + media->serial();
+
+	return name;
+}
+
 bool PipelineHandlerUVC::match(DeviceEnumerator *enumerator)
 {
 	MediaDevice *media;
@@ -405,8 +438,14 @@  bool PipelineHandlerUVC::match(DeviceEnumerator *enumerator)
 		return false;
 
 	/* Create and register the camera. */
+	std::string name = generateName(media, data->video_->devicePath());
+	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. */