Linux系统下自动搜索USB摄像头地址及设备信息

Linux系统下自动搜索USB摄像头地址及设备信息

在进行到多个USB摄像头开发时,会涉及到获取摄像头地址及设备信息问题。

一般USB摄像头的设备信息是固定的,我们基于设备信息,就可以在软件开发时进行有选择性地使用特定摄像头。

整个代码测试环境:Ubuntu18.04,使用Cmake编译

完整的工程代码:https://github.com/chunqiangqian/ScanCamera

搜索USB摄像头的主程序:

#include "scane.h"

int v4l2_open(const char* name, int flag)
{
    int fd = open(name, flag);
    if(fd < 0)
    {
        printf("ERR(%s):failed to open %s\n", __func__, name);
        return -1;
    }

    return fd;
}


int v4l2_close(int fd)
{
    if(close(fd))
    {
        printf("ERR(%s):failed to close v4l2 dev\n", __func__);
        return -1;
    }

    return 0;
}

int v4l2_querycap(int fd, struct v4l2_capability* cap)
{
    if (ioctl(fd, VIDIOC_QUERYCAP, cap) < 0)
    {
        printf("ERR(%s):VIDIOC_QUERYCAP failed\n", __func__);
        return -1;
    }

    return 0;
}

int v4l2_enuminput(int fd, int index, char* name)
{
    struct v4l2_input input;
    int found = 0;

    input.index = 0;
    while(!ioctl(fd, VIDIOC_ENUMINPUT, &input))
    {
        //printf("input:%s\n", input.name);

        if(input.index == index)
        {
            found = 1;
            strcpy(name, (char*)input.name);
        }

        ++input.index;
    }

    if(!found)
    {
        //printf("%s:can't find input dev\n", __func__);
        return -1;
    }

    return 0;
}


int usb_camera_open(const char *dev, v4l2_buf** mV4l2Buf, std::string &card)
{
	int cameraFd = v4l2_open(dev, O_RDWR);
	if(cameraFd < 0)
	{
		printf("open %s failed\r\n", dev);
		return -1;
	}
    // get camera info
	struct v4l2_capability cap;
	int ret = v4l2_querycap(cameraFd, &cap);
    if(ret < 0)
    {
    	printf("set v4l2_querycap failed\r\n");
		return -1;
	}
    else
    {
        //std::cout << "card: " << cap.card << '\n';
        //std::cout << "driver: " << cap.driver << '\n';
        //std::cout << "bus info: " << cap.bus_info << '\n';
        //std::cout << "device cap: " << cap.device_caps << '\n';
        card = (char*)(cap.card);

    }

	if(!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE))
	{
		printf("capabilities failed\r\n");
		return -1;
	}
    
	char devName[100];
	ret = v4l2_enuminput(cameraFd, 0, devName);
    if(ret < 0)
    {
		//printf("v4l2_enuminput failed\r\n");
		return -1;
	}
    
	return cameraFd;

}


void ScaneCameras()
{
    struct v4l2_buf* mV4l2Buf;
    std::string card;
    
    struct dirent *ent;
    char path_[] = "/dev";
    DIR *dir = opendir(path_);
    if (dir != NULL) {
        while ((ent = readdir(dir)) != NULL){
            // 截取部分char,这里只截取前5个
            char filename[5];
            strncpy(filename, ent->d_name, 5);
            // 字符串比较,并获取完整的摄像头路径
            if (strcmp(filename, "video") == 0) {
                //printf("%s\n", ent->d_name);
                std::string camPath;
                camPath.append("/dev/");
                camPath.append(ent->d_name);
                int cameraDevFd = usb_camera_open(camPath.c_str(), &mV4l2Buf, card);
                if (cameraDevFd > 0) {
                    // 摄像头路径
                    printf("%s\n", ent->d_name);
                    // 摄像头信息
                    std::cout << "card: " << card << '\n';
                    //std::cout << "cameraDevFd: " << cameraDevFd << '\n';
                }
                
            }
        }
        closedir(dir);
        
    } else{
        perror("opendir error");
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值