这段时间在忙毕业设计,正好需要用到v4l2,就整理了下它的API,希望对大家有些帮助。
小弟不才,但希望能够把这篇文章作为一篇十分好用的v4l2基础教程,留给以后学习v4l2的朋友。能力有限,错误的地方还希望大家及时留言更正,我会第一时间更新。先感谢所有认识的和不认识的朋友的支持!
PS. 不建议从头来看这篇文章,打开它放到一边,用到某个结构体时就回来用ctrl+f 来找。这篇文章主要是介绍V4L2的控制命令和数据结构,关于V4L2的其他一些细节(如应用开发流程),将在下一篇文章中列出,本篇用到的例子可以在这里找到 http://blog.youkuaiyun.com/yinjingyu_bisheng/article/details/8947138 。
{
跟boss鲁交流了下,像摄像头这样的设备一般是有自己独立的存储器件的---用于缓冲,采集到的数据也确实是先放到这里。但驱动是访问不到这里的。
应用程序、驱动、内存还有设备的数据缓冲存储器的关系如图
}
一、VIDIOC_QUERYCAP 和 v4l2_capability
1、命令功能:查询视频设备的功能(感觉这个功能是鸡肋)
2、结构体:这个结构体由应用程序创建,然后传给驱动,由驱动完成填写
struct v4l2_capability {
__u8 driver[16]; /* 设备驱动的名字 */
__u8 card[32]; /* i.e. 设备的硬件描述信息 */
__u8 bus_info[32]; /* 总线信息 */
__u32 version; /* 保存驱动的版本号 */
__u32 capabilities; /* 一个位掩码用来描述驱动能做的事情 */
__u32 reserved[4]; /*保留的。V4L2规则要求要求reserved被置为0*/
};
3、实例
struct v4l2_capability cap;
ioctl (fd, VIDIOC_QUERYCAP, &cap);
二、VIDIOC_S_FMT 和 v4l2_format
1、设置设备的视频捕获格式(告诉设备生产什么样的数据),当硬件正在工作或缓冲帧已经开辟,则返回失败。
//当设备作为捕获设备用时,该命令对应的驱动回调函数是:
int (*vidioc_s_fmt_cap)(struct file *file, void *private_data,struct v4l2_format *f);
2、v4l2_format :描述一个帧的具体格式,如:一帧的宽度、高度等
struct v4l2_format
{
enum v4l2_buf_type type; // 用来表明数据帧的类型,技巧:如果你做的实验跟我一样都是想用摄像头来采集数据,那么这个字段永远都是V4L2_BUF_TYPE_VIDEO_CAPTURE(包括在其他数据结构中出现此字段)
union
{
struct v4l2_pix_format pix; //一个像素的描述,宽度高度等
struct v4l2_window win;
struct v4l2_vbi_format vbi;
struct v4l2_sliced_vbi_format sliced;
__u8 raw_data[200];
} fmt;
};
再把涉及到的相关结构体也贴出来
a、v4l2_pix_format : 描述一个像素的信息,很多字段都是顾名思义的,所以就不解释这个结构体了
struct v4l2_pix_format
{
__u32 width;
__u32 height;
__u32 pixelformat;
enum v4l2_field field;
__u32 bytesperline;
__u32 sizeimage;
enum v4l2_colorspace;
__u32 priv;
}
3、实例:
struct v4l2_format fmt;
CLEAR (fmt); //#define CLEAR(x) memset (&(x), 0, sizeof (x))
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; //数据帧类型
fmt.fmt.pix.width = 640;
fmt.fmt.pix.height = 480;
fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; //数据的存储类型,一个像素是用YUYV即4:2:2格式还是RGB的形式表示一个点
fmt.fmt.pix.field = V4L2_FIELD_INTERLACED; //没看懂:一帧由交错的两个field的组成
ioctl (fd, VIDIOC_S_FMT, &fmt); //正式设置设备驱动的帧捕获格式
</