NVIDIA主控接入USB摄像头

前言

在使用USB摄像头经常遇到一些问题, 这种问题无论是驱动的稳定性还是硬件的小问题(采集异常),归根到底是设备节点/dev/video0没有,又或者在某一时间片节点掉了后,又恢复了,节点编号变化了,因此导致应用层的服务中断。或者是 基于此, 做了如下几种方式解决。


一、采用udev规则

1)创建一个rules文件, 可以参照/etc/udev/rules.d/下的文件创建,例如:

KERNEL=="video[02]", SUBSYSTEM=="video4linux", ATTRS{idVendor}=="114d", ATTRS{idProduct}=="8589", SYMLINK+="v4l/main"
KERNEL=="video[13]", SUBSYSTEM=="video4linux", ATTRS{idVendor}=="114d", ATTRS{idProduct}=="8589", SYMLINK+="v4l/main_video"

其中114d8589修改为USB厂家的VID:PID,如何查看?linux下使用命令lsusb查看,结果如下:

Bus 002 Device 002: ID 114d:8589 Alpha Imaging Technology Corp.

如果修改后立即生效, service udev reload;service udev restart
2)该方式会自动建立VID:PID对应厂家的设备的一个软连接,使用如下命令查看:

root@ubuntu-desktop:/home/ubuntu/app# ls -l /dev/v4l/main 
lrwxrwxrwx 1 root root 9 11月 17  2020 /dev/v4l/main -> ../video0

注意:

  1. 在某种情况下出现失效,比如USB总线上增加了深度相机,可能会失效(在NANO上接入深度相机确认失效了),因为深度相机也是采用该方式,所以可能有一定冲突,目前暂未解决该ISSUE,因此有了其他替代方式。
  2. 该方式只在NVIDIA中尝试, 国产音视频芯片未做验证尝试。

二、检测USB设备的方式

该方式是备用方式,需要一直轮询设备是否存在,如果不存在,做一些去初始化的动作。
对于比较多的usb摄像头(在/dev/下有多个video),usb的设备如下:

crw-rw----+ 1 root video   81, 0 5月  25 09:38 /dev/video0	//采集卡
crw-rw----+ 1 root video   81, 3 5月  25 09:38 /dev/video1	//采集卡
crw-rw-rw-+ 1 root plugdev 81, 6 5月  25 09:38 /dev/video2	//深度相机
crw-rw-rw-+ 1 root plugdev 81, 7 5月  25 09:38 /dev/video3	//深度相机
crw-rw-rw-+ 1 root plugdev 81, 8 5月  25 09:38 /dev/video4	//深度相机
crw-rw----+ 1 root video   81, 9 5月  25 09:38 /dev/video5	//USB摄像头

如果只对USB监测,如下代码是发现USB摄像头是否存在的接口,返回0表示成功,非0表示失败,对应的错误码FISHEYS_NON_EXISTD表示未发现USB摄像头,PIPE_READ_ERRORPIPE调用失败。

MV_S32 FindFishEyeCamera(char *pName)
{
	char videoInodeBuf[MIN_STRING] = {0}, cmdString[MIN_STRING] = {0};
	char lsusbBuf[MAX_STRING*2] = {0};
	std::string videoPath[5]={""};
	static int flag = 1;
	if(!pName){TRACK_LOG(LOG_ERROR, RED_START "ERROR:" COLOR_END); return MV_FAILURE;}
	
	/* Find VID/PID */
	FILE *pPipe = (FILE*)0;
	if(!pPipe)
 	{
		
		snprintf(cmdString, MIN_STRING, "lsusb");
	 	pPipe = popen(cmdString, "r");
	 	if(!pPipe)
	 	{
	 		TRACK_LOG(LOG_ERROR, RED_START "PIPE FAILURE!" COLOR_END);
			
	 	}
	 	fread(lsusbBuf, sizeof(MV_U8), MAX_STRING*2, pPipe);
	 	pclose(pPipe); pPipe = (FILE*)0;
		/**
		 * "0c45:6366" strings edit "0c45" because the fisheye camera when update version
		 	cause "4366" become "4361".
		 */
		if(MV_NULL == strstr(lsusbBuf, "0c45"/*:6366*/))
		{
			TRACK_LOG(LOG_ERROR, RED_START "鱼眼镜头不存在!" COLOR_END);
			return FISHEYS_NON_EXISTD;
			
		}
	//	TRACK_LOG(LOG_INFO, GREEN_START "Fisheye camera exitstd." COLOR_END);
 	}
	/*get inode*/
	if(!pPipe)
 	{
		//剔除RS2的设备节点	
		snprintf(cmdString, MIN_STRING, "ls -l /dev/video* |grep -v plugdev |awk '{print $10}'");
	 	pPipe = popen(cmdString, "r");
	 	if(!pPipe)
	 	{
	 		TRACK_LOG(LOG_ERROR, RED_START "PIPE FAILURE!" COLOR_END);
			return PIPE_READ_ERROR;
	 	}
	 //	fread(videoInodeBuf, sizeof(MV_U8), MIN_STRING, pPipe);
		int line = 0;
		while(!feof(pPipe))
		{
			if(fgets(videoInodeBuf, MIN_STRING, pPipe))
			{
				
				
				videoPath[line] = videoInodeBuf;
				if(flag){
				    TRACK_LOG(LOG_INFO, "video_path:%s", videoPath[line].c_str());
					flag = 0;
				}
				line++;
			}	
		}
		pclose(pPipe); pPipe = (FILE*)0;
		
		if(line >= 3 )
		{
			
			memcpy(pName, videoPath[2].c_str(), strlen(videoPath[2].c_str()));
			
		}
		else
		{
			
			
			return FISHEYS_NON_EXISTD;
		}
		
	 	
 	}

	return MV_SUCCESS;
}

展望

如果有其他更好的解决方案, 麻烦评论留言,互相讨论学习。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值