Ubutun 安装V4L库
sudo apt-get install libv4l-dev
直接使用如上命令即可安装。
V4L2介绍 V4L与V4L2的区别
V4L是 Video for Linux的缩写,它是Linux 内核中关于视频设备的子系统,它为linux 下的视频驱动提供了统一的接口,使得应用程序可以使用统一的API 函数操作不同的视频设备,极大地简化了视频系统的开发和维护。
由于早期的 V4L 有很多缺陷,Bill Dirks 等人对其进行了重新设计,并取名为Video for Linux 2(V4L2使用),最早出现于Linux2.5.x 版本。V4L2 相比于V4L 有更好的扩展性和灵活性,并且支持的硬件设备更多。
因此在应用程序V4L编程实际是指v4l2,我们这个系列的以V4L2为主,但由于历史的原因,V4L2一般兼容V4L.所以很多程序可以用V4L接口。
V4L2(Video4Linux的缩写)是Linux下关于视频采集相关设备的驱动框架,为驱动和应用程序提供了一套统一的接口规范。
V4L2支持的设备十分广泛,但是其中只有很少一部分在本质上是真正的视频设备:
Video capture device : 从摄像头等设备上获取视频数据。对很多人来讲,video capture是V4L2的基本应用。设备名称为/dev/video,主设备号81,子设备号0~63
Video output device : 将视频数据编码为模拟信号输出。与video capture设备名相同。
Video overlay device : 将同步锁相视频数据(如TV)转换为VGA信号,或者将抓取的视频数据直接存放到视频卡的显存中。
Video output overlay device :也被称为OSD(On-Screen Display)
VBI device : 提供对VBI(Vertical Blanking Interval)数据的控制,发送VBI数据或抓取VBI数据。设备名/dev/vbi0~vbi31,主设备号81,子设备号224~255
Radio device : FM/AM发送和接收设备。设备名/dev/radio0~radio63,主设备号81,子设备号64~127
V4L2应用层
V4L2是一个字符设备,而V4L2的大部分功能都是通过设备文件的ioctl导出的。
可以将这些ioctl分类如下:
Query Capability:查询设备支持的功能,只有VIDIOC_QUERY_CAP一个。
优先级相关:包括VIDIOC_G_PRIORITY,VIDIOC_S_PRIORITY,设置优先级。
capture相关:视频捕获相关Ioctl。
V4L2采集需要使用的ID
接下来我们就开始写代码,开始使用V4L2采集摄像头数据。
一、重写ioctl函数
这样保证设置IO不会因为中断而停止,并且保证了IO设置。
static inline int camera_ioctl(int fd, int request, void *arg)
{
int r = -1;
do
{
r = ioctl(fd, request, arg);
} while (r < 0 && EINTR == errno);
return r;
}
二、打开文件
在linux下‘一点哲学’,所以我们此时需要去打开摄像头对应虚拟化后的文件(注意,要将虚拟机的摄像头连接上,在虚拟机->可移动设备->USB Camera 断开与主机的连接)此时可以在/dev下找到video0(针对不同主机对应可能为video1、video0);
int open_camear_device(const char *path)
{
int fd = open(path, O_RDWR, 0);
if (-1 == fd)
{
perror("Open camera device:");
return -1;
}
return fd;
}
三、我们需要初始化虚拟设备
//初始化
int init_camera(int fd)
{
//检查摄像头设备,获取信息。
v4l2_capability cap;
if (-1 == camera_ioctl(fd, VIDIOC_QUERYCAP, &cap))
{
perror("ictol cap!");
return -1;
}
if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE))
{
fprintf(stderr, "is no video capture device\n");
return -1;
}
if (!(cap.capabilities & V4L2_CAP_STREAMING))
{
fprintf(stderr, "does not support streaming i/o\n");
return -1;
}
//打印摄像头相关信息
printf