简介
V4L2是内核提供给应用程序的音视频访问的统一接口,在Linux上,免驱摄像头是通过UVC(USB video class)挂载到V4L框架上实现的免驱。
V4L2的ioctl命令和相关结构体的操作
查询摄像头的相关属性
命令
#define VIDIOC_QUERYCAP _IOR('V', 0, struct v4l2_capability)
结构体
struct v4l2_capability {
__u8 driver[16];//驱动名称
__u8 card[32];//卡的名称
__u8 bus_info[32];//总线名称
__u32 version;//驱动版本
__u32 capabilities;//设备支持的操作
__u32 reserved[3];//保留字段
};
对于capabilities
,查询设备支持的功能,查询其是否支持视频捕获
程序查询设备属性
ret = ioctl(fd,VIDIOC_QUERYCAP,&cap);
if(ret < 0)
{
cout << "VIDIOC_QUERYCAP error" << endl;
return -1;
}
cout << "card: "<< cap.card << endl;
cout << "driver: " << cap.driver << endl;
cout << "bus_info: " << cap.bus_info << endl;
if(cap.capabilities&V4L2_CAP_VIDEO_CAPTURE)//判断这个设备是否是视频捕获设备
cout << "this is a video capture device" << endl;
设置查询序号,帧格式,获取摄像头支持的格式
命令
#define VIDIOC_ENUM_FMT _IOWR('V', 2, struct v4l2_fmtdesc)
结构体
struct v4l2_fmtdesc {
__u32 index; /*序号,需要自己在应用程序中设置 */
__u32 type; /* 帧类型,需要自己设置*/
__u32 flags; /* 标志位,表示是否压缩图像 */
__u8 description[32]; /* 描述字符串,一般输出压缩格式*//*JPEG无损压缩,PNG有损压缩*/
__u32 pixelformat; /* RGB的设置,RGB888,RGB565等,在.h文件中有详细说明 */
__u32 reserved[4];
};
查询格式(有的支持不只一种压缩格式通过index递增查询所有),输出查询到的压缩格式
struct v4l2_fmtdesc fmtdesc;
fmtdesc.index = 0;
fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
while( ioctl(fd, VIDIOC_ENUM_FMT, &fmtdesc)>=0 )
{
cout << fmtdesc.index << ": description: " << fmtdesc.description <<endl;
fmtdesc.index++;
}
查询和设置当前设备的格式
命令
#define VIDIOC_G_FMT _IOWR('V', 4, struct v4l2_format)
#define VIDIOC_S_FMT _IOWR('V', 5, struct v4l2_format)
结构体
struct v4l2_format {
__u32 type;
union {
struct v4l2_pix_format pix; /*视频捕获设备相关 */
struct v4l2_pix_format_mplane pix_mp; /* V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE */
struct v4l2_window win; /* V4L2_BUF_TYPE_VIDEO_OVERLAY */
struct v4l2_vbi_format vbi; /* V4L2_BUF_TYPE_VBI_CAPTURE */
struct v4l2_sliced_vbi_format sliced; /* V4L2_BUF_TYPE_SLICED_VBI_CAPTURE */
__u8 raw_data[200]; /* user-defined */
} fmt;
};
对于摄像头,一般只看第一个结构体struct v4l2_pix_format
struct v4l2_pix_format {
__u32 width;//图像宽
__u32 height;//图像高
__u32 pixelformat;//像素格式
__u32 field; /* enum v4l2_field */
__u32 bytesperline; /* for padding, zero if unused */
__u32 sizeimage;
__u32 colorspace; /* 色彩空间, */
__u32 priv; /* private data, depends on pixelformat */
};
编程获取格式化信息
struct v4l2_format fmt;
ret = ioctl(fd, VIDIOC_G_FMT, &fmt);
if(ret < 0)
{
cout << "VIDIOC_G_FMT error" << endl;
return -1;
}
cout << "type: " << fmt.type << endl;
cout << "width: " << fmt.fmt.pix.width << endl;
cout << "heigth: " << fmt.fmt.pix.height << endl;
cout << "colorspace: " << fmt.fmt.pix.colorspace << endl;
运行效果中打印的colorspace
等信息,实际2是个枚举的枚举值,在头文件中可以找到其枚举子,查看实际意义。