前言:在学习VI之前,希望大家能够对V4L2的架构有一定的了解,因为RV1126的VI模块的底层就是采用V4L2来进行处理。
1.什么是VI模块
RV1126的VI模块指的是视频输入模块,它的作用是读取sensor的数据。VI模块底层就是对V4L2驱动架构接口的一系列的封装,它本质上还是依赖Linux底层的V4L2驱动架构并向应用层提供对应的设备文件节点,比方说(/dev/video*)。而VI模块可以通过操作类似于/dev/video*这样的设备节点来读取摄像头数据。
2.RV1126的VI模块重要参数
上图是VI模块的结构体参数,我们来解释一下上面每个参数的意义:
pcVideoNode:VIDEO视频节点路径,RV1126的视频节点是以下面的截图为基准
注意:从上面的截图我们可以看到。在RV1126里面,视频节点一般以rkispp_开头的,它一般映射到/dev/video*的某个设备节点。一般情况下,我们都是用rkispp_scale0作为开发的视频节点。
u32Width:视频输入的宽度,一般和CMOS摄像头或者外设的宽度一致。
u32Height:视频输入的高度,一般和CMOS摄像头或者外设的高度一致。
enPixFmt:视频输入的图像格式,默认是NV12(IMAGE_TYPE_NV12)
u32BufCnt:VI捕获视频缓冲区计数,默认是3,下图是缓冲区计数的图解
VI_CHN_BUF_TYPE:VI捕捉视频的类型,这里面有两种。一种是DMA模式(VI_CHN_BUF_TYPE_DMA)、另外一种是MMAP模式(VI_CHN_BUF_TYPE_MMAP):
**DMA:指的是直接访问内存的方式,相当于音视频数据直接从硬件传输到内存里面。这种方式的优点就是两边传输的速度非常之快,但缺点就是非常消耗硬件资源,对硬件外设资源要求较高。具体的原理如下图所示:
**MMAP:指的是内存映射,这种方式就是把硬件外设、磁盘的文件映射到虚拟内存上面。然后用户只需要对虚拟内存进行读写操作就可以对硬件外设进行操作了。这种方法的优点是用户不需要直接操作硬件就能够修改硬件的内容,换言之就是对硬件的消耗没那么大。但是缺点就是:第一,它的读写速度相对DMA来说没那么快;第二,有时候硬件写到虚拟内存的数据可能会出现丢失情况,导致数据出现丢失的情况。
3.RV1126的VI模块初始化API
上面已经把VI模块的参数详细介绍了一遍,下面我们重点讲解VI模块的初始化和使能API。
3.1.RK_MPI_VI_SetChnAttr讲解:
RK_MPI_VI_SetChnAttr主要功能就是设置VI通道属性,这里面要传入三个参数:ViPipe(管道号)、ViChn(通道号)、VI_CHN_ATTR_S结构体指针。
ViPipe:VI管道号,在RV1126中输入的图像数据会通过管道pipe进行存储。换言之设备sensor和pipe之间有可能是一对一或者一对多的关系,而在RV1126中VI管道号对应sensor的数量,VI管道默认从0开始。比方说一个双目摄像头,分别是camera0、camera1。camera0对应的管道号是pipe0,camera1对应的管道号是pipe1。
ViChn:Vi通道号,指的是一个Vi管道里面,有多少个通道能用(但前提是ViChn没有被占用,若被占用则此通道无法被使用)。通常来说Vi通道号和管道号的数值是相同的。在RV1126中管道号和通道号共同决定某个摄像头的某个摄像头数据,下图是ViPipe和ViChn的关系:
从图片可以看到,每个Camera的Vipipe最多对应8个通道数(ViChn),MAX_CHN的值是8。
VI_CHN_ATTR_S:第三个参数就是VI_CHN_ATTR_S的结构体指针,在这里就不做太多的解释,因为在上面已经讲解完。
3.2RK_MPI_VI_EnableChn讲解:
RK_MPI_VI_EnableChn主要功能就是使能VI通道,传入的第一个参数是ViPipe管道号、第二个ViChn通道号。