在应用程序获取视频数据的流程中,都是通过 ioctl 命令与驱动程序进行交互,常见的 ioctl 命令有:
1 VIDIOC_QUERYCAP /* 获取设备支持的操作 */
2 VIDIOC_G_FMT /* 获取设置支持的视频格式 */
3 VIDIOC_S_FMT /* 设置捕获视频的格式 */
4 VIDIOC_REQBUFS /* 向驱动提出申请内存的请求 */
5 VIDIOC_QUERYBUF /* 向驱动查询申请到的内存 */
6 VIDIOC_QBUF /* 将空闲的内存加入可捕获视频的队列 */
7 VIDIOC_DQBUF /* 将已经捕获好视频的内存拉出已捕获视频的队列 */
8 VIDIOC_STREAMON /* 打开视频流 */
9 VIDIOC_STREAMOFF /* 关闭视频流 */
10 VIDIOC_QUERYCTRL /* 查询驱动是否支持该命令 */
11 VIDIOC_G_CTRL /* 获取当前命令值 */
12 VIDIOC_S_CTRL /* 设置新的命令值 */
13 VIDIOC_G_TUNER /* 获取调谐器信息 */
14 VIDIOC_S_TUNER /* 设置调谐器信息 */
15 VIDIOC_G_FREQUENCY /* 获取调谐器频率 */
16 VIDIOC_S_FREQUENCY /* 设置调谐器频率 */
1、struct v4l2_capability 与 VIDIOC_QUERYCAP
VIDIOC_QUERYCAP 命令通过结构 v4l2_capability 获取设备支持的操作模式:
1 struct v4l2_capability {
2 __u8 driver[16]; /* i.e. "bttv" */
3 __u8 card[32]; /* i.e. "Hauppauge WinTV" */
4 __u8 bus_info[32]; /* "PCI:" + pci_name(pci_dev) */
5 __u32 version; /* should use KERNEL_VERSION() */
6 __u32 capabilities; /* Device capabilities */
7 __u32 reserved[4];
8 };
其中域 capabilities 代表设备支持的操作模式,常见的值有 V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING 表示是一个视频捕捉设备并且具有数据流控制模式;另外 driver 域需要和 struct video_device 中的 name 匹配。
2、struct v4l2_format 与 VIDIOC_G_FMT、VIDIOC_S_FMT、VIDIOC_TRY_FMT
通常用 VIDIOC_S_FMT 命令通过结构 v4l2_format 初始化捕获视频的格式,如果要改变格式则用 VIDIOC_TRY_FMT 命令:
1 struct v4l2_format {
2 enum v4l2_buf_type type;
3 union {
4 struct v4l2_pix_format pix; /* V4L2_BUF_TYPE_VIDEO_CAPTURE */
5 struct v4l2_window win; /* V4L2_BUF_TYPE_VIDEO_OVERLAY */
6 struct v4l2_vbi_format vbi; /* V4L2_BUF_TYPE_VBI_CAPTURE */
7 struct v4l2_sliced_vbi_format sliced; /* V4L2_BUF_TYPE_SLICED_VBI_CAPTURE */
8 __u8 raw_data[200]; /* user-defined */
9 } fmt;
10 };
11 其中
12 enum v4l2_buf_type {
13 V4L2_BUF_TYPE_VIDEO_CAPTURE = 1,
14 V4L2_BUF_TYPE_VIDEO_OUTPUT = 2,
15 V4L2_BUF_TYPE_VIDEO_OVERLAY = 3,
16 ...
17 V4L2_BUF_TYPE_PRIVATE = 0x80,
18 };
19
20 struct v4l2_pix_format {
21 __u32 width;
22 __u32 height;
23 __u32 pixelformat;
24 enum v4l2_field field;
25 __u32 bytesperline; /* for padding, zero if unused */
26 __u32 sizeimage;
27 enum v4l2_colorspace colorspace;
28 __u32 priv; /* private data, depends on pixelformat */
29 };
常见的捕获模式为 V4L2_BUF_TYPE_VIDEO_CAPTURE 即视频捕捉模式,在此模式下 fmt 联合体采用域 v4l2_pix_format:其中 width 为视频的宽、height 为视频的高、pixelformat 为视频数据格式(常见的值有 V4L2_PIX_FMT_YUV422P | V4L2_PIX_FMT_RGB565)、bytesperline 为一行图像占用的字节数、sizeimage 则为图像占用的总字节数、colorspace 指定设备的颜色空间。
3、struct v4l2_requestbuffers 与 VIDIOC_REQBUFS
VIDIOC_REQBUFS 命令通过结构 v4l2_requestbuffers 请求驱动申请一片连续的内存用于缓存视频信息:
1 struct v4l2_requestbuffers {
2 __u32 count;
3 enum v4l2_buf_type type;
4 enum v4l2_memory memory;
5 __u32 reserved[2];
6 };
7 其中
8 enum v4l2_memory {
9 V4L2_MEMORY_MMAP = 1,
10 V4L2_MEMORY_USERPTR = 2,
11 V4L2_MEMORY_OVERLAY = 3,
12 };
count 指定根据图像占用空间大小申请的缓存区个数,type 为视频捕获模式,memory 为内存区的使用方式。
4、struct v4l2_buffer与 VIDIOC_QUERYBUF
VIDIOC_QUERYBUF 命令通过结构 v4l2_buffer 查询驱动申请的内存区信息:
1 struct v4l2_buffer {
2 __u32 index;
3 enum v4l2_buf_type type;
4 __u32 bytesused;
5 __u32 flags;
6 enum v4l2_field field;
7 struct time