V4L2快速入门

一.V4L2操作流程

1.打开设备

2.配置(获取支持格式)

3.申请内核缓冲区队列

4.把内核的缓冲区队列映射到用户空间

5.开始采集

6.采集数据

7.停止采集

8.释放映射

9.关闭设备

二.打开设备

本次使用的是usb外接摄像头

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
int main(void)
{
	//1.打开设备
	int fd = open("/dev/video0", O_RDWR);
	if(fd < 0)
	{
		perror("打开设备失败");
		return -1;
	}
	//9.关闭设备
	close(fd);
	return 0;
}

三.获取支持格式

cd /usr/include/linux

vi videodev2.h

找到2179行

 获取摄像头格式VIDIOC_ENUM_FMT--对应存储格式的结构体struct v4l2_fmtdesc

比如:VIDIOC_ENUM_FMT对应的是struct v4l2_fmtdesc 
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];
};
enum v4l2_buf_type {
        V4L2_BUF_TYPE_VIDEO_CAPTURE        = 1,
        V4L2_BUF_TYPE_VIDEO_OUTPUT         = 2,
        V4L2_BUF_TYPE_VIDEO_OVERLAY        = 3,
        V4L2_BUF_TYPE_VBI_CAPTURE          = 4,
        ...
};
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/videodev2.h>
int main(void)
{
	//1.打开设备
	int fd = open("/dev/video0", O_RDWR);
	if(fd < 0)
	{
		perror("打开设备失败");
		return -1;
	}
	//2.获取摄像头支持的格式ioctl(文件描述符, 命令, 与命令对应的结构体)
	struct v4l2_fmtdesc v4fmt;
	v4fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
	int i=0;
	while(1)
	{
		v4fmt.index = i++;  
		int ret = ioctl(fd, VIDIOC_ENUM_FMT, &v4fmt);
		if(ret < 0)
		{
			perror("获取失败");
			break;
		}
		printf("index=%d\n", v4fmt.index);
		printf("flags=%d\n", v4fmt.flags);
		printf("description=%s\n", v4fmt.description);
		unsigned char *p = (unsigned char *)&v4fmt.pixelformat;
		printf("pixelformat=%c%c%c%c\n", p[0],p[1],p[2],p[3]);
		printf("reserved=%d\n", v4fmt.reserved[0]);
	}
	//9.关闭设备
	close(fd);
	return 0;
}

四.配置摄像头的采集格式

#define VIDIOC_S_FMT            _IOWR('V',  5, struct v4l2_format) 
struct v4l2_format {
        __u32    type;
        union {
                struct v4l2_pix_format          pix;     /* V4L2_BUF_TYPE_VIDEO_CAPTURE */
                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 */
                struct v4l2_sdr_format          sdr;     /* V4L2_BUF_TYPE_SDR_CAPTURE */
                __u8    raw_data[200];                   /* user-defined */
        } fmt;
};

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;     /* enum v4l2_colorspace */
        __u32                   priv;           /* private data, depends on pixelformat */
        __u32                   flags;          /* format flags (V4L2_PIX_FMT_FLAG_*) */
        __u32                   ycbcr_enc;      /* enum v4l2_ycbcr_encoding */
        __u32                   quantization;   /* enum v4l2_quantization */
        __u32                   xfer_func;      /* enum v4l2_xfer_func */
};
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/videodev2.h>
#include <string.h>

int main(void)
{
	//1.打开设备
	int fd = open("/dev/video0", O_RDWR);
	if(fd < 0)
	{
		perror("打开设备失败");
		return -1;
	}

	//3.设置采集格式
	struct v4l2_format vfmt;
	vfmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;//摄像头采集
	vfmt.fmt.pix.width = 640;//设置宽(不能任意)
	vfmt.fmt.pix.height = 480;//设置高
	vfmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;//设置视频采集格式
	int ret = ioctl(fd, VIDIOC_S_FMT, &vfmt);
	if(ret < 0)
	{
		perror("设置格式失败");
	}

	memset(&vfmt, 0, sizeof(vfmt));
	vfmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
	ret  = ioctl(fd, VIDIOC_G_FMT, &vfmt);
	if(ret < 0)
	{
		perror("获取格式失败");
	}

	if(vfmt.fmt.pix.width == 640 && vfmt.fmt.pix.height == 480 && 
	vfmt.fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV)
	{
		printf("设置成功\n");
	}else
	{
		printf("设置失败\n");
	}
	
	//9.关闭设备
	close(fd);
	return 0;
}

五. 申请内核缓冲区队列

#define VIDIOC
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小徐的记事本

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值