[RFC,v1,18/20] pipeline: uvcvideo: Factor out camera ID generation
diff mbox series

Message ID 20260918080734.1228227-19-naush@raspberrypi.com
State New
Headers show
Series
  • libcamera: New enumeration API
Related show

Commit Message

Naushir Patuck Sept. 18, 2026, 7:59 a.m. UTC
Extract the camera ID computation from UVCCameraData::generateId() into a
helper taking the sysfs path of the device backing the video node. The
path is available from the media entity device numbers without opening
the video device, which will allow generating the same ID when surveying
cameras at enumeration time.

This will be used in a subsequent commit when adding the camera survey
mechanism to the uvcvideo pipeline handler.

Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
---
 src/libcamera/pipeline/uvcvideo/uvcvideo.cpp | 127 ++++++++++---------
 1 file changed, 68 insertions(+), 59 deletions(-)

Patch
diff mbox series

diff --git a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp
index 4b09bd6e2f7c..5fa1bdb0ff0e 100644
--- a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp
+++ b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp
@@ -129,6 +129,72 @@  std::optional<controls::ExposureTimeModeEnum> v4l2ToExposureMode(int32_t x)
 	}
 }
 
+/*
+ * Generate the camera ID from the sysfs path of the UVC device video node. The
+ * path is derived from the device numbers of the media entity, so the ID can be
+ * generated without opening the video device.
+ */
+std::string generateIdFromPath(const std::string &path)
+{
+	/* Create a controller ID from first device described in firmware. */
+	std::string controllerId;
+	std::string searchPath = path;
+	while (true) {
+		std::string::size_type pos = searchPath.rfind('/');
+		if (pos <= 1) {
+			LOG(UVC, Error) << "Can not find controller ID";
+			return {};
+		}
+
+		searchPath = searchPath.substr(0, pos);
+
+		controllerId = sysfs::firmwareNodePath(searchPath);
+		if (!controllerId.empty())
+			break;
+	}
+
+	/*
+	 * Create a USB ID from the device path which has the known format:
+	 *
+	 *	path = bus, "-", ports, ":", config, ".", interface ;
+	 *	bus = number ;
+	 *	ports = port, [ ".", ports ] ;
+	 *	port = number ;
+	 *	config = number ;
+	 *	interface = number ;
+	 *
+	 * Example: 3-2.4:1.0
+	 *
+	 * The bus is not guaranteed to be stable and needs to be stripped from
+	 * the USB ID. The final USB ID is built up of the ports, config and
+	 * interface properties.
+	 *
+	 * Example 2.4:1.0.
+	 */
+	std::string usbId = utils::basename(path.c_str());
+	usbId = usbId.substr(usbId.find('-') + 1);
+
+	/* Creata a device ID from the USB devices vendor and product ID. */
+	std::string deviceId;
+	for (const char *name : { "idVendor", "idProduct" }) {
+		std::ifstream file(path + "/../" + name);
+
+		if (!file.is_open())
+			return {};
+
+		std::string value;
+		std::getline(file, value);
+		file.close();
+
+		if (!deviceId.empty())
+			deviceId += ":";
+
+		deviceId += value;
+	}
+
+	return controllerId + "-" + usbId + "-" + deviceId;
+}
+
 } /* namespace */
 
 UVCCameraConfiguration::UVCCameraConfiguration(UVCCameraData *data)
@@ -628,66 +694,9 @@  int UVCCameraData::init(std::shared_ptr<MediaDevice> media)
 
 bool UVCCameraData::generateId()
 {
-	const std::string path = video_->devicePath();
+	id_ = generateIdFromPath(video_->devicePath());
 
-	/* Create a controller ID from first device described in firmware. */
-	std::string controllerId;
-	std::string searchPath = path;
-	while (true) {
-		std::string::size_type pos = searchPath.rfind('/');
-		if (pos <= 1) {
-			LOG(UVC, Error) << "Can not find controller ID";
-			return false;
-		}
-
-		searchPath = searchPath.substr(0, pos);
-
-		controllerId = sysfs::firmwareNodePath(searchPath);
-		if (!controllerId.empty())
-			break;
-	}
-
-	/*
-	 * Create a USB ID from the device path which has the known format:
-	 *
-	 *	path = bus, "-", ports, ":", config, ".", interface ;
-	 *	bus = number ;
-	 *	ports = port, [ ".", ports ] ;
-	 *	port = number ;
-	 *	config = number ;
-	 *	interface = number ;
-	 *
-	 * Example: 3-2.4:1.0
-	 *
-	 * The bus is not guaranteed to be stable and needs to be stripped from
-	 * the USB ID. The final USB ID is built up of the ports, config and
-	 * interface properties.
-	 *
-	 * Example 2.4:1.0.
-	 */
-	std::string usbId = utils::basename(path.c_str());
-	usbId = usbId.substr(usbId.find('-') + 1);
-
-	/* Creata a device ID from the USB devices vendor and product ID. */
-	std::string deviceId;
-	for (const char *name : { "idVendor", "idProduct" }) {
-		std::ifstream file(path + "/../" + name);
-
-		if (!file.is_open())
-			return false;
-
-		std::string value;
-		std::getline(file, value);
-		file.close();
-
-		if (!deviceId.empty())
-			deviceId += ":";
-
-		deviceId += value;
-	}
-
-	id_ = controllerId + "-" + usbId + "-" + deviceId;
-	return true;
+	return !id_.empty();
 }
 
 void UVCCameraData::addControl(uint32_t cid, const ControlInfo &v4l2Info,