When I tested the camera, I found that the video node number occasionally changes. As a result, I cannot always use a fixed video node number (e.g., /dev/video5) for the camera. Why?
Obtain the Target Device ID Before Using the Camera
The assigned node number for a video device may vary depending on the probe order during boot-up. This means that the video device node (e.g., /dev/video5) is not guaranteed to remain consistent across reboots. It is important to verify the correct video device node before using the camera.
For example, if the USB camera is connected to the EVK before boot-up, the UVC driver will probe the USB camera before the SoC camera. In this case, the SoC-related video device node number will be incremented.
Here are two methods for locating the target video device.
- Using the V4L2 Utility -
v4l2-ctl - Enumerating Video Devices in Applications
Using the V4L2 Utility - v4l2-ctl
The v4l2-ctl tool can help identify available video devices. To list all video devices, execute the following command:
# Use v4l2-ctl to list all video device
v4l2-ctl --list-devices
This command displays a list of all v4l devices.
Enumerating Video Devices in Applications
In the application implementation, it is advisable to enumerate all available video device nodes and search for the target node based on its name and expected capabilities. This method ensures that the application selects the correct video device, regardless of the assigned node numbers.
For example, the following code enumerates all video devices and prints their driver names.
#include <fcntl.h>
#include <iostream>
#include <linux/videodev2.h>
#include <sys/ioctl.h>
#include <unistd.h>
using namespace std;
int main() {
string path_prefix = "/dev/video";
struct v4l2_capability vcap;
int vfd;
cout << "Video Device\tDriver" << endl;
for (unsigned int idx = 0; ; idx++) {
string path = path_prefix + to_string(idx);
if (access(path.c_str(), F_OK) != 0)
break;
vfd = open(path.c_str(), O_RDWR | O_CLOEXEC | O_NONBLOCK);
if (vfd < 0)
continue;
if (ioctl(vfd, VIDIOC_QUERYCAP, &vcap) < 0) {
close(vfd);
continue;
}
cout << path << "\t" << vcap.driver << endl;
close(vfd);
}
return 0;
}
For more information about querying capabilities, please refer to The Linux kernel - Querying Capabilities.