工作流程:
打开设备--> 检查和设备设备属性-->设置帧格式-->设置一种输入输出的方法(缓冲区管理)-->循环获取数据-->关闭设备
1. 打开视频设备
fd = open("/dev/video0",O_RDWR);
2.查询视频设备能力 VIDIOC_QUERYCAP
ioctl_ops(fd,VIDIOC_QUERYCAP,&cap);
if(!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)){
perror("this is not cap");
return -1;
}
struct v4l2_capability cap;
struct v4l2_capability {
__u8 driver[16]; 驱动名词
__u8 card[32]; 设备名字
__u8 bus_info[32]; 设备在系统中的位置
__u32 version; 驱动版本号
__u32 capabilities; 设置支持的操作
__u32 device_caps;
__u32 reserved[3];
};
/* Values for 'capabilities' field */
#define V4L2_CAP_VIDEO_CAPTURE 0x00000001 /* Is a video capture device */
#define V4L2_CAP_VIDEO_OUTPUT 0x00000002 /* Is a video output device */
#define V4L2_CAP_VIDEO_OVERLAY 0x00000004 /* Can do video overlay */
#define V4L2_CAP_VBI_CAPTURE 0x00000010 /* Is a raw VBI capture device */
#define V4L2_CAP_VBI_OUTPUT 0x00000020 /* Is a raw VBI output device */
#define V4L2_CAP_SLICED_VBI_CAPTURE 0x00000040 /* Is a sliced VBI capture device */
#define V4L2_CAP_SLICED_VBI_OUTPUT 0x00000080 /* Is a sliced VBI output device */
#define V4L2_CAP_RDS_CAPTURE 0x00000100 /* RDS data capture */
#define V4L2_CAP_VIDEO_OUTPUT_OVERLAY 0x00000200 /* Can do video output overlay */
#define V4L2_CAP_HW_FREQ_SEEK 0x00000400 /* Can do hardware frequency seek */
#define V4L2_CAP_RDS_OUTPUT 0x00000800 /* Is an RDS encoder */
一般我们需要的是 V4L2_CAP_VIDEO_CAPTURE
调用底层 例如:
static int vidioc_querycap(struct file *file, void *priv,
struct v4l2_capability *cap)
{
struct vivid_dev *dev = video_drvdata(file);
strcpy(cap->driver, "vivid");
strcpy(cap->card, "vivid");
snprintf(cap->bus_info, sizeof(cap->bus_info),
"platform:%s", dev->v4l2_dev.name);
cap->capabilities = dev->vid_cap_caps | dev->vid_out_caps |
dev->vbi_cap_caps | dev->vbi_out_caps |
dev->radio_rx_caps | dev->radio_tx_caps |
dev->sdr_cap_caps | V4L2_CAP_DEVICE_CAPS;
return 0;
}
3.查询视频设备输出的格式 // 一般可以不做直接设置即可
VIDIOC_ENUM_FMT
int ioctl(int fd, int request, struct v4l2_fmtdesc *argp);
/*
* F O R M A T E N U M E R A T I O N
*/
struct v4l2_fmtdesc {
__u32 index; /* Format number */
__u32 type; /* enum v4l2_buf_type */
__u32 flags;
__u8 description[32]; /* Description string */
__u32 pixelformat; /* Format fourcc */
__u32 reserved[4];
};
4.设置视频采集格式
1. 设置摄像头的格式
2. 设置图片的长度,宽度,图片格式
//VIDIOC_S_FMT
my_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE ;
my_fmt.fmt.pix.width = 720;
my_fmt.fmt.pix.height = 576;
my_fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
ioctl(fd, VIDIOC_S_FMT, &my_fmt);
/**
* struct v4l2_format - stream data format
* @type: enum v4l2_buf_type; type of the data stream
* @pix: definition of an image format
* @pix_mp: definition of a multiplanar image format
* @win: definition of an overlaid image
* @vbi: raw VBI capture or output parameters
* @sliced: sliced VBI capture or output parameters
* @raw_data: placeholder for future extensions and custom formats
*/
struct v4l2_format {
__u32 type;
union {
struct v4l2_pix_forma