下面将给出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
V4L2是Video for linux2的简称,为linux中关于视频设备的内核驱动。在Linux中,视频设备是设备文件,可以像访问普通文件一样对其进行读写,摄像头在/dev/video*下,如果只有一个视频设备,通常为/dev/video0。V4L2是内核提供给应用程序访问音、视频驱动的统一接口。V4L2 的相关定义包含在头文件<linux/videodev2.h> 中。
IOCTL的实现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
动态视频采集流程:
部分代码实现:
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 else 17 { 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对应唯一结构体
我板载上装的是Logitch c270摄像头,从摄像头支持的图像像素输出的信息可以看出,在Hi3559板载上可以支持2种像素格式,这里选用的是V4L2_PIX_FMT_YUV422 格式。从生成image的大小可以判断出是正确的(YUV422数据大小 = 长 * 宽 * 1.5 = 640 * 480 * 2 = 614400 bytes = 600k)可以将image文件拷出来,使用pYUV 软件查看YUV图片。这里需要注意,使用pYUV 查看YUV图片的时候,需要正确设置图片格式,按我上面代码采集的数据格式,最后一帧图片输出结果如下:
之后随笔将推出结合MPP平台实现视频流的输出。
问题:
在虚拟机上,脚本运行正常,但是会卡在视频采集处,个人认为是虚拟机的缓存问题,而板载缓存比较充足,所以能够很好实现。
Hi3559AV100外接UVC/MJPEG相机实时采图设计(二):V4L2接口的实现(以YUV422为例)
原文:https://www.cnblogs.com/iFrank/p/14403397.html