简体   繁体   English

从 C 应用程序 (Linux) 获取连接的 USB 摄像头(网络摄像头)的 v4l2 设备号

[英]Getting the v4l2 device number for a connected USB camera (webcam) from a C application (Linux)

I'm working on a embedded linux system (yocto based) and I'm trying to simply get a list of the camera USB video devices (webcams) numbers with the related connected usb port from a C program. I'm working on a embedded linux system (yocto based) and I'm trying to simply get a list of the camera USB video devices (webcams) numbers with the related connected usb port from a C program.

I'm able to get the devices list with vendor ID and connected port doing this:我可以通过以下方式获取带有供应商 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);

}

What I need now is to know (from the C application) what v4l2 device number is related to the usb camera port, eg.我现在需要知道(来自 C 应用程序)什么 v4l2 设备号与 usb 相机端口相关,例如。 I've got two webcam (same vendor ID) connected which appear as /dev/video0 and /dev/video1 respectively and I can get the connected port for each one using the above code, but, how can I know which ports are connected each one?我连接了两个网络摄像头(相同的供应商 ID),分别显示为 /dev/video0 和 /dev/video1,我可以使用上面的代码为每个摄像头获取连接的端口,但是,我怎么知道连接了哪些端口每一个?

I tried to get information from the devices using ioctl calls as it is recommended in this question but when I run the code:我尝试按照此问题中的建议使用 ioctl 调用从设备获取信息,但是当我运行代码时:

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;
}

I've got the next errors:我有下一个错误:

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

If I'm checking through command line for instance I can get the capabilities without issues running:例如,如果我通过命令行进行检查,我可以获得这些功能而不会出现问题:

v4l2-ctl --device-/dev/video0 --list-formats-ext

Any ideas how can this be done?任何想法如何做到这一点?

Thanks in advance.提前致谢。

I don't know if this specifically answers your question, but you can get useful information by globbing certain patterns under /dev or /sys, for example this will return the full device path (including PCI bus) of each video device,我不知道这是否专门回答了您的问题,但是您可以通过在 /dev 或 /sys 下查找某些模式来获得有用的信息,例如这将返回每个视频设备的完整设备路径(包括 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);
    }
  }
}

On one system with 2 cameras this prints,在一个带有 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

Other interesting glob strings include /dev/v4l/by-id/* and /dev/v4l/by-path/* .其他有趣的 glob 字符串包括/dev/v4l/by-id/*/dev/v4l/by-path/*

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM