以下Uvc Camera摄像头的演示过程均在盈鹏飞嵌入式AHD-T507主板上进行,如果其他公司主板,可能略有区别。
AHD-T507简要介绍如下:

AHD-T507产品特性:
采用Allwinner公司Cortex-A53四核T507处理器,运行最高速度为1.5GHZ;
支持Mali-G31 MP2 GPU,支持OpenGL ES 3.2/2.0/1.0, Valkan 1.1,OpenCL 2.0
支持4K/25fps H.264视频编码,支持4K/15fps MJPEG编码;
多格式4K/60fps视频解码 (H.265,H.264,VC-1, MPEG-1/2/4, VP8) ;
支持双屏异显;支持RGB666/LVDS,分辨率最高1920x1080/60fps;支持HDMI 2.0A, 分辨率最高4K/60fps;支持TV CVBS OUT(NTSC/PAL);
支持1-2G Bytes LPDDR4 SDRAM;
支持EMMC 4G-64G大容量电子盘,可启动;
支持SDIO3.0,5路USB2.0 HOST和一路OTG,1路I2C,4路RS485, 2路PWM(应用于背光)
支持双路以太网,一路10/100M;一路10/100/1000M;
支持3G/4G通信;
支持6路AHD视频输入;
稳定的操作系统的支持,可预装Android10.0/LINUX 4.9/UBUNTU 20.04;
尺寸为:146*132MM
1.相关概念
1.1 UVC
UVC全称为USB Video Class,即:USB视频类,是一种为USB视频捕获设备定义的协议标准。UVC是Microsoft与另外几家设备厂商联合推出的为USB视频捕获设备定义的协议标准,已成为USB org标准之一。支持 USB Video Class (UVC) standard 1.1可以让相机在所有的作业系统以及平台中使用(Windows, Linux, Mac etc.)。用户只需连接相机便可进行图像传输,而无需安装任何驱动程序 。
简单点说,就是只要USB摄像头是UVC摄像头,那这个摄像头的驱动就遵循一个通用的格式,可以实现免驱的操作。在Linux系统中,UVC驱动的支持在Linux Kernel 2.4之后被增加到内核中。但是为了让内核识别到这款摄像头,还要告诉内核这个USB的ID是UVC设备才行。
UVC设备的PID和VID简介
每个USB设备都有VID(Vender ID,供应商识别码)和PID(Product ID,产品识别码),两者的长度均为2Byte。PID和VID是主机识别USB设备时使用。
主机检测到USB设备后,首先会通过USB Class查询插入的是什么设备。检测到插入设备的类型后,通过读取和检索VID和PID,主机就能知道当前连接的设备的类型,并能了解应该给这个USB设备加载什么样的驱动程序进行通信。
例如,我们插入了U盘
1.系统首先会检测插入USB设备的Class。
2.U盘的Class是0x08 —— Mass Storage。那么就会按照USB大容量存储设备的方式对USB设备进行操作。
3.同时,系统还会查看设备的VID和PID,识别该U盘的制造商和型号,并查看是否需要加载特殊的驱动。
1.2 Linux下V4L2简介
V4L2是Video for linux2的简称,是linux中关于视频设备的内核驱动。在Linux中,视频设备是设备文件,可以像访问普通文件一样对其进行读写或是MMAP。
摄像头的设备节点在/dev/video下,如果只有一个视频设备,通过为/dev/video0,也有可能是/dev/uvcvideo。
1.3 V4L2视频采集原理
参考100ask-摄像头V4L2编程应用开发
使用V4L2采集图像,需要对收集到的图像进行如下步骤:
1.分配帧缓冲区
2.将分配到的帧缓冲区从内核空间映射到用户空间
3.将申请到的帧缓冲区在视频采集输入队列中排队
4.等待数据的到来
数据传输流程:
1.首先驱动程序采集一帧图像数据,并放入第一个帧缓冲区
2.第一个帧缓冲区存满一帧图像数据后,将该缓冲区放入视频采集输出队列,等待应用程序取出
3.应用程序取出图像数据后可以对图像数据进行处理或存储操作,然后将该帧缓冲区放入视频采集输入队列的尾部
4.驱动程序采集下一帧数据,放入第二个缓冲区,存满一帧数据后放入输出队列
循环上面几步,就可以实现循环采集。流程图如下:

1.4 V4L2应用程序实现流程
V4L2视频采集一般分为以下5步:
1.打开设备,进行初始化参数设置,通过V4L2接口设置视频图像的采集窗口、采集的点阵大小和格式;
2.申请图像帧缓冲,并进行内存映射,将这些帧缓冲从内核空间映射到用户空间,便于应用程序读取、处理图像数据;
将帧缓冲进行入队操作,启动视频采集;
4.驱动开始视频数据的采集,应用程序从视频采集输出队列取出帧缓冲区,处理完后,将帧缓冲区重新放入视频采集输入队列,循环往复采集连续的视频数据;
5.释放资源,停止采集工作。

1.4.* 一些常用的命令表示符
(1)VIDIOC_REQBUFS:分配内存;
(2)VIDIOC_QUERYBUF:把VIDIOC_REQBUFS中分配的数据缓存转换成物理地址;
(3)VIDIOC_QUERYCAP:查询驱动功能;
(4)VIDIOC_ENUM_FMT:获取当前驱动支持的视频格式;
(5)VIDIOC_S_FMT:设置当前驱动的视频捕获格式;
(6)VIDIOC_G_FMT:读取当前驱动的视频捕获格式;
(7)VIDIOC_TRY_FMT:验证当前驱动的显示格式;
(8)VIDIOC_CROPCAP:查询驱动的修剪功能;
(9)VIDIOC_S_CROP:设置视频信号的边框;
(10)VIDIOC_G_CROP:读取视频信号的边框;
(11)VIDIOC_QBUF:把数据从缓存中读取出来;
(12)VIDIOC_DQBUF:把数据放回缓存队列;
(13)VIDIOC_STREAMOP:开始视频显示函数;
(14)VIDIOC_STREAMOFF:结束视频显示函数;
(15)VIDIOC_QUERYSTD:检查当前视频设备支持的标准,例如PAL或NTSC;
2.环境搭建
本部分参考https://blog.csdn.net/u010034969/article/details/115210890
首先需要在内核中添加UVC支持,为了让这个板子正常识别到这个摄像头,需要在内核中打开UVC摄像头的编译,并将摄像头的PID和VID加入到代码中。
2.1 内核添加UVC支持
2.1.1 查看PID与VID
将摄像头插入电脑USB接口,借助windows的设备管理器,查看对应摄像头的属性。并在详细信息中找到硬件ID。

得到其vid和pid:
VID:0x0C45
PID:0x64AB
保存PID和VID备用。
2.1.2 内核图形配置界面添加UVC设备支持
进入内核根目录,make menuconfig进入内核编译配置。打开如下几项

下面直接引用参考链接【1】的图。
1.进入Device Drivers → Multimedia support → Media USB Adapters,找到并开启USB Video Class(UVC)如下图:

如果找不到这项,说明是相关的依赖项未打开。可以搜索关键词USB_VIDEO_CLASS,能看到这项的依赖项:

将所有依赖项设置为Y(编译进内核)即可。

2.1.3 内核中增加摄像头的PID和VID
打开内核代码driver/media/usb/uvc/uvc_driver.c,找到usb_device_id结构体uvc_ids。仿照其他摄像头的代码,添加摄像头的PID和VID:


完成后make整个内核,并将内核烧写入硬件平台中。
启动平台后插入摄像头,如果出现如下uvc的打印信息,显示出了摄像头的PID&VID并挂在了input下,则说明添加成功。

可以通过如下指令查看新增的设备节点。

在这里新增的是/dev/video1。
以上工作,在AHD-T507主板上都已经做好,启动后,在/etc/rcS已经默认加载UVC相关驱动模块:
#test uvc camera;
insmod /lib/modules/4.9.170/videobuf2-vmalloc.ko
insmod /lib/modules/4.9.170/uvcvideo.ko
看到了/dev/video下的节点,那么我们就可以开起qt程序video camera程序,如下图:

网友评论