下面将给出Hi3559AV100外接UVC/MJPEG相机实时采图设计的整体流程,主要实现是通过V4L2接口将UVC/MJPEG相机采集的数据送入至MPP平台,经过VDEC、VPSS、VO最后通过HDMI的输出,给出(二)V4L2接口的实现。
可以先参照前面随笔介绍(一)Linux USB摄像头驱动加载与分析:https://www.cnblogs.com/iFrank/p/14399421.html
板载平台:BOXER-8410AI
芯片型号:Hi3559AV100
相机型号:Logitch c270
开发环境:VM15.5+ubuntu16.04+Hilinux
1、V4L2接口说明
V4L2是Video for linux2的简称,为linux中关于视频设备的内核驱动。在Linux中,视频设备是设备文件,可以像访问普通文件一样对其进行读写,摄像头在/dev/video*下,如果只有一个视频设备,通常为/dev/video0。V4L2是内核提供给应用程序访问音、视频驱动的统一接口。V4L2 的相关定义包含在头文件<linux/videodev2.h> 中。
V4L2 支持两种方式来采集图像:内存映射(mmap)和直接读取方式(read)。V4L2 在/usr/include/linux/videodev2.h 文件下定义了一些重要的数据结构,在采集图像的过程中,就是通过对这些数据的操作来获得最终的图像数据。Linux 系统 V4L2 使能可在内核编译阶段配置,默认情况下是在 make menuconfig 是打开的。应用程序可以通过 V4L2 进行视频采集。V4L2 支持内存映射(mmap)方式和直接读取方式(read)方式采集数据。前者一般用于连续的视频数据采集,后者常用静态图片数据采集。v4l2 中不仅定义了通用 API 元素,图像的格式,输入/输出方法,还定义了Linux 内核驱动处理视频信息的一系列接口,这些接口主要有:
视频采集接口——Video Capture interface;
视频输出接口——Video Output Interface;
视频覆盖/预览接口——Video Overlay Interface;
视频输出覆盖接口——Video Output Overlay Interface;
编解码接口——Codec Interface
IOCTL的实现V4L2的控制
打开视频设备后,可以设置该视频设备的属性,例如裁剪、缩放等。这一步是可选的。在Linux编程中,一般使用ioctl函数来对设备的I/O通道进行管理:extern int ioctl (int __fd, unsigned long int __request, …) __THROW;
__fd:设备的ID,例如刚才用open函数打开视频通道后返回的cameraFd;
__request:具体的命令标志符。
在进行V4L2开发中,一般会用到以下的命令标志符:
1:分配内存 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_STREAMON:开始视频显示函数14 VIDIOC_STREAMOFF:结束视频显示函数15 VIDIOC_QUERYSTD:检查当前视频设备支持的标准,例如PAL或NTSC。
这些IO调用,有些是必须的,有些是可选择的,其命令标志符在在头文件<linux/videodev2.h> 定义,具体如下:
1 #define VIDIOC_QUERYCAP _IOR('V', 0, struct v4l2_capability)2 #define VIDIOC_RESERVED _IO('V', 1)3 #define VIDIOC_ENUM_FMT _IOWR('V', 2, struct v4l2_fmtdesc)4 #define VIDIOC_G_FMT _IOWR('V', 4, struct v4l2_format)5 #define VIDIOC_S_FMT _IOWR('V', 5, struct v4l2_format)6 #define VIDIOC_REQBUFS _IOWR('V', 8, struct v4l2_requestbuffers)
Logitch c270支持的像素格式有两种:
1 YUYV 4:2:2 2 Motion-JPEG
2、V4L2的实现流程
一般来说V4L2 采集视频数据分为五个步骤:首先,打开视频设备文件,进行视频采集的参数初始化,通过 V4L2 接口设置视频图像的采集窗口、采集的点阵大小和格式;
其次,申请若干视频采集的帧缓冲区,并将这些帧缓冲区从内核空间映射到用户空间,便于应用程序读取/处理视频数据;
第三,将申请到的帧缓冲区在视频采集输入队列排队,并启动视频采集;
第四,驱动开始视频数据的采集,应用程序从视频采集输出队列取出帧缓冲区,处理完后,将帧缓冲区重新放入视频采集输入队列,循环往复采 集连续的视频数据;
第五,停止视频采集。在本次设计中,定义了几个函数实现对摄像头的配置和采集。
一帧图片采集流程:
动态视频采集流程:
图解过程已经很详细了,重新总结下。整个过程:
首先:先启动视频采集,驱动程序开始采集一帧数据,把采集的数据放入视频采集输入队列的第一个帧缓冲区,一帧数据采集完成,也就是第
一个帧缓冲区存满一帧数据后,驱动程序将该帧缓冲区移至视频采集输出队列,等待应用程序从输出队列取出。驱动程序则继续采集下一帧数据放入第二个缓冲区,同样帧缓冲区存满下一帧数据后,被放入视频采集输出队列。
然后:应用程序从视频采集输出队列中取出含有视频数据的帧缓冲区,处理帧缓冲区中的视频数据,如存储或压缩。
最后:应用程序将处理完数据的帧缓冲区重新放入视频采集输入队列,这样可以循环采集。我们从摄像头中获取的视频帧数据会放入视频缓存队列中,当其他模块需要处理对应的视频帧的时候,就会占用缓存块,也就是这一块内存被占用,当处理完之后,对应的数据通过 VO/VENC/VDA 显示之后,这一缓存块就没有用了,可以回收利用。现在来看,其实海思的底层处理和 linux 的底层处理是一样的。不过海思本身使用的就是 linux 内核。应该也就是对这一块进行封装了而已吧!
海思的公共视频缓存池按我的理解应该有两部分,一部分是视频采集输入队列,另一部分是视频采集输出队列,VI 通道是是视频采集输出队列中获取的视频帧,而中间 linux 内核的驱动程序会在视频采集输入队列中填充视频帧,变成视频输出队列。
部分代码实现:
1 /*打开视频*/ 2 if ((fd = open(FILE_VIDEO, O_RDWR)) == -1) 3 { 4 printf("Error opening V4L interface\n"); 5 return (FALSE); 6 } 7 8 /*读video_capability中信息。 9 通过调用IOCTL函数和接口命令VIDIOC_QUERYCAP查询10 摄像头的信息*/11 if (ioctl(fd, VIDIOC_QUERYCAP, &cap) == -1)12 {13 printf("Error opening device %s: unable to query device.\n",FILE_VIDEO);14 return (FALSE);15 }16 else17 {18 printf("driver:\t\t%s\n",cap.driver);19 printf("card:\t\t%s\n",cap.card);20 printf("bus_info:\t%s\n",cap.bus_info);21 printf("version:\t%d\n",cap.version);22 printf("capabilities:\t%x\n",cap.capabilities);23 24 /*其中capabilities: 4000001通过与各种宏位与,25 可以获得物理设备的功能属性*/26 if ((cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) == V4L2_CAP_VIDEO_CAPTURE)27 {28 printf("Device %s: supports capture.\n",FILE_VIDEO);29 }30 31 if ((cap.capabilities & V4L2_CAP_STREAMING) == V4L2_CAP_STREAMING)32 {33 printf("Device %s: supports streaming.\n",FILE_VIDEO);34 }35 } //VIDIOC_QUERYCAP对应唯一结构体
3、V4L2测试(640×480像素一帧图片输出)
我板载上装的是Logitch c270摄像头,从摄像头支持的图像像素输出的信息可以看出,在Hi3559板载上可以支持2种像素格式,这里选用的是V4L2_PIX_FMT_YUV422 格式。从生成image的大小可以判断出是正确的(YUV422数据大小 = 长 * 宽 * 1.5 = 640 * 480 * 2 = 614400 bytes = 600k)可以将image文件拷出来,使用pYUV 软件查看YUV图片。这里需要注意,使用pYUV 查看YUV图片的时候,需要正确设置图片格式,按我上面代码采集的数据格式,最后一帧图片输出结果如下:
之后随笔将推出结合MPP平台实现视频流的输出。
问题:
在虚拟机上,脚本运行正常,但是会卡在视频采集处,个人认为是虚拟机的缓存问题,而板载缓存比较充足,所以能够很好实现。
原文转载:http://www.shaoqun.com/a/555575.html
Zozo:https://www.ikjzd.com/w/2180
cicpa考试:https://www.ikjzd.com/w/1375
下面将给出Hi3559AV100外接UVC/MJPEG相机实时采图设计的整体流程,主要实现是通过V4L2接口将UVC/MJPEG相机采集的数据送入至MPP平台,经过VDEC、VPSS、VO最后通过HDMI的输出,给出(二)V4L2接口的实现。可以先参照前面随笔介绍(一)LinuxUSB摄像头驱动加载与分析:https://www.cnblogs.com/iFrank/p/14399421.html
mav:mav
海带宝:海带宝
口述:婚后老公总为一些小事挑我刺:口述:婚后老公总为一些小事挑我刺
最新发现:卖家再也无法从PayPal上获取买家电子邮箱地址了!:最新发现:卖家再也无法从PayPal上获取买家电子邮箱地址了!
早起鸟儿会爆单 | 亚马逊欧洲站Hidden Gems大促提报攻略:早起鸟儿会爆单 | 亚马逊欧洲站Hidden Gems大促提报攻略
No comments:
Post a Comment