从 C 应用程序获取连接的 USB 摄像头(网络摄像头)的 v4l2 设备号 (Linux)
Getting the v4l2 device number for a connected USB camera (webcam) from a C application (Linux)
我正在开发一个嵌入式 linux 系统(基于 yocto),我试图简单地从一个C程序.
我可以通过执行此操作获得包含供应商 ID 和连接端口的设备列表:
void usbdevs()
{
libusb_device*** list=NULL;
libusb_context *context = NULL;
ssize_t count;
uint8_t port;
char ncameras=0;
libusb_init(&context);
count = libusb_get_device_list(context,&list);
for(int i=0; i < MAX_NUM_CAMS; i++)
usb_dev_list[i]=0;
for (size_t idx = 0; idx < count; ++idx) {
libusb_device *device = list[idx];
struct libusb_device_descriptor desc = {0};
libusb_get_device_descriptor(device, &desc);
port = libusb_get_port_number(device);
printf("Vendor:Device = %04x:%04x Port: %d\n", desc.idVendor, desc.idProduct,port);
}
libusb_free_device_list(list, count);
libusb_exit(context);
}
我现在需要知道(从 C 应用程序)什么 v4l2 设备号与 usb 相机端口相关,例如。我连接了两个网络摄像头(相同的供应商 ID),分别显示为 /dev/video0 和 /dev/video1,我可以使用上面的代码为每个摄像头获取连接的端口,但是,我怎么知道哪些端口每个都连接了吗?
我尝试按照建议使用 ioctl 调用从设备获取信息 in this question 但是当我 运行 代码时:
int checkvideodev()
{
int fd;
struct video_capability video_cap;
struct video_window video_win;
struct video_picture video_pic;
if((fd = open("/dev/video0", O_RDONLY)) == -1){
perror("cam_info: Can't open device");
return 1;
}
if(xioctl(fd, VIDIOCGCAP, &video_cap) == -1)
perror("cam_info: Can't get capabilities");
else {
printf("Name:\t\t '%s'\n", video_cap.name);
printf("Minimum size:\t%d x %d\n", video_cap.minwidth, video_cap.minheight);
printf("Maximum size:\t%d x %d\n", video_cap.maxwidth, video_cap.maxheight);
}
if(xioctl(fd, VIDIOCGWIN, &video_win) == -1)
perror("cam_info: Can't get window information");
else
printf("Current size:\t%d x %d\n", video_win.width, video_win.height);
if(xioctl(fd, VIDIOCGPICT, &video_pic) == -1)
perror("cam_info: Can't get picture information");
else
printf("Current depth:\t%d\n", video_pic.depth);
close(fd);
return 0;
}
我遇到了下一个错误:
cam_info: Can't get capabilities: Inappropriate ioctl for device
cam_info: Can't get window information: Inappropriate ioctl for device
cam_info: Can't get picture information: Inappropriate ioctl for device
例如,如果我通过命令行进行检查,我可以获得这些功能而不会出现问题 运行ning:
v4l2-ctl --device-/dev/video0 --list-formats-ext
知道如何做到这一点吗?
提前致谢。
我不知道这是否专门回答了您的问题,但是您可以通过在 /dev 或 /sys 下匹配某些模式来获得有用的信息,例如,这将 return 完整的设备路径(包括 PCI每个视频设备的总线),
#include <glob.h>
#include <unistd.h>
void list_videos() {
int i;
glob_t globbuf;
if (glob("/sys/class/video4linux/video*", 0, NULL, &globbuf) != 0) {
perror("glob");
return;
}
for (i=0; i < globbuf.gl_pathc; i++) {
char buf[256] = {};
if (readlink(globbuf.gl_pathv[i], buf, sizeof(buf)-1) > 0) {
puts(buf);
}
}
}
在一个带有 2 个摄像头的系统上打印,
../../devices/pci0000:00/0000:00:14.0/usb2/2-1/2-1.1/2-1.1:1.0/video4linux/video0
../../devices/pci0000:00/0000:00:14.0/usb2/2-3/2-3:1.0/video4linux/video1
其他有趣的 glob 字符串包括 /dev/v4l/by-id/*
和 /dev/v4l/by-path/*
。
我正在开发一个嵌入式 linux 系统(基于 yocto),我试图简单地从一个C程序.
我可以通过执行此操作获得包含供应商 ID 和连接端口的设备列表:
void usbdevs()
{
libusb_device*** list=NULL;
libusb_context *context = NULL;
ssize_t count;
uint8_t port;
char ncameras=0;
libusb_init(&context);
count = libusb_get_device_list(context,&list);
for(int i=0; i < MAX_NUM_CAMS; i++)
usb_dev_list[i]=0;
for (size_t idx = 0; idx < count; ++idx) {
libusb_device *device = list[idx];
struct libusb_device_descriptor desc = {0};
libusb_get_device_descriptor(device, &desc);
port = libusb_get_port_number(device);
printf("Vendor:Device = %04x:%04x Port: %d\n", desc.idVendor, desc.idProduct,port);
}
libusb_free_device_list(list, count);
libusb_exit(context);
}
我现在需要知道(从 C 应用程序)什么 v4l2 设备号与 usb 相机端口相关,例如。我连接了两个网络摄像头(相同的供应商 ID),分别显示为 /dev/video0 和 /dev/video1,我可以使用上面的代码为每个摄像头获取连接的端口,但是,我怎么知道哪些端口每个都连接了吗?
我尝试按照建议使用 ioctl 调用从设备获取信息 in this question 但是当我 运行 代码时:
int checkvideodev()
{
int fd;
struct video_capability video_cap;
struct video_window video_win;
struct video_picture video_pic;
if((fd = open("/dev/video0", O_RDONLY)) == -1){
perror("cam_info: Can't open device");
return 1;
}
if(xioctl(fd, VIDIOCGCAP, &video_cap) == -1)
perror("cam_info: Can't get capabilities");
else {
printf("Name:\t\t '%s'\n", video_cap.name);
printf("Minimum size:\t%d x %d\n", video_cap.minwidth, video_cap.minheight);
printf("Maximum size:\t%d x %d\n", video_cap.maxwidth, video_cap.maxheight);
}
if(xioctl(fd, VIDIOCGWIN, &video_win) == -1)
perror("cam_info: Can't get window information");
else
printf("Current size:\t%d x %d\n", video_win.width, video_win.height);
if(xioctl(fd, VIDIOCGPICT, &video_pic) == -1)
perror("cam_info: Can't get picture information");
else
printf("Current depth:\t%d\n", video_pic.depth);
close(fd);
return 0;
}
我遇到了下一个错误:
cam_info: Can't get capabilities: Inappropriate ioctl for device
cam_info: Can't get window information: Inappropriate ioctl for device
cam_info: Can't get picture information: Inappropriate ioctl for device
例如,如果我通过命令行进行检查,我可以获得这些功能而不会出现问题 运行ning:
v4l2-ctl --device-/dev/video0 --list-formats-ext
知道如何做到这一点吗?
提前致谢。
我不知道这是否专门回答了您的问题,但是您可以通过在 /dev 或 /sys 下匹配某些模式来获得有用的信息,例如,这将 return 完整的设备路径(包括 PCI每个视频设备的总线),
#include <glob.h>
#include <unistd.h>
void list_videos() {
int i;
glob_t globbuf;
if (glob("/sys/class/video4linux/video*", 0, NULL, &globbuf) != 0) {
perror("glob");
return;
}
for (i=0; i < globbuf.gl_pathc; i++) {
char buf[256] = {};
if (readlink(globbuf.gl_pathv[i], buf, sizeof(buf)-1) > 0) {
puts(buf);
}
}
}
在一个带有 2 个摄像头的系统上打印,
../../devices/pci0000:00/0000:00:14.0/usb2/2-1/2-1.1/2-1.1:1.0/video4linux/video0
../../devices/pci0000:00/0000:00:14.0/usb2/2-3/2-3:1.0/video4linux/video1
其他有趣的 glob 字符串包括 /dev/v4l/by-id/*
和 /dev/v4l/by-path/*
。