[Camera]v4l2用户空间

参考:
1. 《android驱动开发权威指南》
2.  YellowMax2001 https://blog.csdn.net/u013904227/category_9277668.html
3.  linux Kernel source code: 4.4

简介

v4l2接口种类

​ V4L2在设计时,是要支持很多广泛的设备的,它们之中只有一部分在本质上是真正的视频设备:

可以支持多种设备,它可以有以下几种接口:

  1. 视频采集接口(video capture interface):这种应用的设备可以是高频头或者摄像头。V4L2的最初设计就是应用于这种功能的。

  2. 视频输出接口(video output interface):可以驱动计算机的外围视频图像设备--像可以输出电视信号格式的设备。

  3. 直接传输视频接口(video overlay interface):它的主要工作是把从视频采集设备采集过来的信号直接输出到输出设备之上,而不用经过系统的CPU。

  4. 视频间隔消隐信号接口(VBI interface):它可以使应用可以访问传输消隐期的视频信号。

  5. 收音机接口(radio interface):可用来处理从AM或FM高频头设备接收来的音频流。

v4l2 设备节点

​ V4l2的主设备号是81,次设备号为0~255;这些次设备号有分为多类设备:视频设备,Radio设备,VBI设备等。因此v4l2对应的节点有:/dev/videoX、/dev/vbiX、/dev/radioX。其中X一般为0~31的顺序号。

在这里插入图片描述

​ v4l2仍然是基于设备-驱动-总线模型,采用典型的分层结构。用户应用程序通过设备节点,使用文件调用接口和ioctl与内核进行交互。

数据结构及指令

常见数据结构及指令

常见数据结构见下表

数据结构作用
struct v4l2_requestbuffers申请帧缓冲,对应命令VIDIOC_REQBUFS
struct v4l2_capability视频设备的功能,对应命令VIDIOC_QUERYCAP
struct v4l2_input视频输入信息,对应命令VIDIOC_ENUMINPUT
struct v4l2_standard视频制式所采用的标准,对应命令VIDIOC_ENUMSTD
struct v4l2_format帧格式,对应命令VIDIOC_G_FMT,VIDIOC_S_FMT
struct v4l2_buffer驱动中一帧图像缓存,对应命令VIDIOC_QUERYBUF
struct v4l2_crop视频信号矩形边框
v4l2_std_id视频制式标准ID号

v4l2常用IOCTL见下表

IOCTL作用
VIDIOC_REQBUFS分配内存
VIDIOC_QUERYBUF数据缓存转换位物理地址
VIDIOC_QUERYCAP查询驱动功能
VIDIOC_ENUM_FMT获取当前支持的视频格式
VIDIOC_S_FMT设置当前视频捕获格式
VIDIOC_G_FMT获取当前视频捕获格式
VIDIOC_TRY_FMT验证当前显示格式
VIDIOC_CROPCAP查询驱动的修剪能力
VIDIOC_S_CROP设置视频信号的矩形边框
VIDIOC_G_CROP读取视频信号的矩形边框
VIDIOC_QBUF把数据从缓存中读取出来
VIDIOC_DQBUF把数据放回缓存队列
VIDIOC_STREAMON开始视频显示函数
VIDIOC_STREAMOFF结束视频显示函数
VIDIOC_QUERYSTD检查当前视频设备支持的标准

详细介绍

v4l2_requestbuffers

struct v4l2_requestbuffers {
	__u32			count;
	__u32			type;		/* enum v4l2_buf_type */
	__u32			memory;		/* enum v4l2_memory */
	__u32			reserved[2];
};

其中type是v4l2_buf_type

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,
	V4L2_BUF_TYPE_VBI_OUTPUT           = 5,
	V4L2_BUF_TYPE_SLICED_VBI_CAPTURE   = 6,
	V4L2_BUF_TYPE_SLICED_VBI_OUTPUT    = 7,
	V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY = 8,
	V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE = 9,
	V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE  = 10,
	V4L2_BUF_TYPE_SDR_CAPTURE          = 11,
	V4L2_BUF_TYPE_SDR_OUTPUT           = 12,
	V4L2_BUF_TYPE_META_CAPTURE         = 13,
	/* Deprecated, do not use */
	V4L2_BUF_TYPE_PRIVATE              = 0x80,
};

memory是v4l2_memory

enum v4l2_memory {
	V4L2_MEMORY_MMAP             = 1,
	V4L2_MEMORY_USERPTR          = 2,
	V4L2_MEMORY_OVERLAY          = 3,
	V4L2_MEMORY_DMABUF           = 4,
};

v4l2_capability

struct v4l2_capability {
	__u8	driver[16];
	__u8	card[32];
	__u8	bus_info[32];
	__u32   version;
	__u32	capabilities;     //整个设备的capabilities
	__u32	device_caps;   //该设备特有的capabilities
	__u32	reserved[3];
};

内核定义了非常多的capabilities,列出部分如下:

#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 */

v4l2_input

struct v4l2_input {
	__u32	     index;		/*  Which input */
	__u8	     name[32];		/*  Label */
	__u32	     type;		/*  Type of input */
	__u32	     audioset;		/*  Associated audios (bitfield) */
	__u32        tuner;             /*  enum v4l2_tuner_type */
	v4l2_std_id  std;
	__u32	     status;
	__u32	     capabilities;
	__u32	     reserved[3];
};

有三种输入类型

#define V4L2_INPUT_TYPE_TUNER		1
#define V4L2_INPUT_TYPE_CAMERA		2
#define V4L2_INPUT_TYPE_TOUCH		3

有五种tuner_type

enum v4l2_tuner_type {
	V4L2_TUNER_RADIO	     = 1,
	V4L2_TUNER_ANALOG_TV	     = 2,
	V4L2_TUNER_DIGITAL_TV	     = 3,
	V4L2_TUNER_SDR               = 4,
	V4L2_TUNER_RF                = 5,
};

非常多种状态,列举部分如下:

/* field 'status' - general */
#define V4L2_IN_ST_NO_POWER    0x00000001  /* Attached device is off */
#define V4L2_IN_ST_NO_SIGNAL   0x00000002
#define V4L2_IN_ST_NO_COLOR    0x00000004

/* field 'status' - sensor orientation */
/* If sensor is mounted upside down set both bits */
#define V4L2_IN_ST_HFLIP       0x00000010 /* Frames are flipped horizontally */
#define V4L2_IN_ST_VFLIP       0x00000020 /* Frames are flipped vertically */

v4l2_standard

struct v4l2_standard {
	__u32		     index;
	v4l2_std_id          id;
	__u8		     name[24];
	struct v4l2_fract    frameperiod; /* Frames, not fields */
	__u32		     framelines;
	__u32		     reserved[4];
};

主要有PAL、NTSC、MTS/BTSC、analog等制式

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 */
		struct v4l2_meta_format		meta;    /* V4L2_BUF_TYPE_META_CAPTURE */
		__u8	raw_data[200];                   /* user-defined */
	} fmt;
};
  • type就是v4l2_buf_type
  • fmt是图像格式。多种标准格式或者自定义图像格式中的一种

v4l2_buffer

struct v4l2_buffer {
	__u32			index;      //帧索引值
	__u32			type;       //v4l2_buf_type
	__u32			bytesused;    //已经使用的bytes
	__u32			flags;          //buffer相关信息的flag
	__u32			field;       //v4l2_field
	struct timeval		timestamp;    //frame timestamp
	struct v4l2_timecode	timecode;    //frame timecode
	__u32			sequence;    

	/* memory location */
	__u32			memory;   //v4l2_memory
	union {
		__u32           offset;          //mmap
		unsigned long   userptr;   //userptr
		struct v4l2_plane *planes;  
		__s32		fd;  //dmabuf
	} m;
	__u32			length;
	__u32			reserved2;
	__u32			reserved;
};
  • 内核定义了许多表示buffer信息的flag,列举部分如下
/* Buffer is mapped (flag) */
#define V4L2_BUF_FLAG_MAPPED			0x00000001
/* Buffer is queued for processing */
#define V4L2_BUF_FLAG_QUEUED			0x00000002
/* Buffer is ready */
#define V4L2_BUF_FLAG_DONE			0x00000004
/* Image is a keyframe (I-frame) */
#define V4L2_BUF_FLAG_KEYFRAME			0x00000008
/* Image is a P-frame */
#define V4L2_BUF_FLAG_PFRAME			0x00000010
/* Image is a B-frame */
#define V4L2_BUF_FLAG_BFRAME			0x00000020
/* Buffer is ready, but the data contained within is corrupted. */
#define V4L2_BUF_FLAG_ERROR			0x00000040
/* timecode field is valid */
#define V4L2_BUF_FLAG_TIMECODE			0x00000100
/* Buffer is prepared for queuing */
#define V4L2_BUF_FLAG_PREPARED			0x00000400
  • v4l2_field
enum v4l2_field {
	V4L2_FIELD_ANY           = 0, /* driver can choose from none,
					 top, bottom, interlaced
					 depending on whatever it thinks
					 is approximate ... */
	V4L2_FIELD_NONE          = 1, /* this device has no fields ... */
	V4L2_FIELD_TOP           = 2, /* top field only */
	V4L2_FIELD_BOTTOM        = 3, /* bottom field only */
	V4L2_FIELD_INTERLACED    = 4, /* both fields interlaced */
	V4L2_FIELD_SEQ_TB        = 5, /* both fields sequential into one
					 buffer, top-bottom order */
	V4L2_FIELD_SEQ_BT        = 6, /* same as above + bottom-top order */
	V4L2_FIELD_ALTERNATE     = 7, /* both fields alternating into
					 separate buffers */
	V4L2_FIELD_INTERLACED_TB = 8, /* both fields interlaced, top field
					 first and the top field is
					 transmitted first */
	V4L2_FIELD_INTERLACED_BT = 9, /* both fields interlaced, top field
					 first and the bottom field is
					 transmitted first */
};

v4l2_crop

struct v4l2_crop {
	__u32			type;	/* enum v4l2_buf_type */
	struct v4l2_rect        c;
};
  • v4l2_rect 四边框
struct v4l2_rect {
	__s32   left;
	__s32   top;
	__u32   width;
	__u32   height;
};

v4l2_std_id

模拟信号标准id,用位表示

#define V4L2_STD_PAL_B          ((v4l2_std_id)0x00000001)
#define V4L2_STD_PAL_B1         ((v4l2_std_id)0x00000002)
#define V4L2_STD_PAL_G          ((v4l2_std_id)0x00000004)
#define V4L2_STD_PAL_H          ((v4l2_std_id)0x00000008)
#define V4L2_STD_PAL_I          ((v4l2_std_id)0x00000010)
#define V4L2_STD_PAL_D          ((v4l2_std_id)0x00000020)
#define V4L2_STD_PAL_D1         ((v4l2_std_id)0x00000040)
#define V4L2_STD_PAL_K          ((v4l2_std_id)0x00000080)

#define V4L2_STD_PAL_M          ((v4l2_std_id)0x00000100)
#define V4L2_STD_PAL_N          ((v4l2_std_id)0x00000200)
#define V4L2_STD_PAL_Nc         ((v4l2_std_id)0x00000400)
#define V4L2_STD_PAL_60         ((v4l2_std_id)0x00000800)

#define V4L2_STD_NTSC_M         ((v4l2_std_id)0x00001000)	/* BTSC */
#define V4L2_STD_NTSC_M_JP      ((v4l2_std_id)0x00002000)	/* EIA-J */
#define V4L2_STD_NTSC_443       ((v4l2_std_id)0x00004000)
#define V4L2_STD_NTSC_M_KR      ((v4l2_std_id)0x00008000)	/* FM A2 */

#define V4L2_STD_SECAM_B        ((v4l2_std_id)0x00010000)
#define V4L2_STD_SECAM_D        ((v4l2_std_id)0x00020000)
#define V4L2_STD_SECAM_G        ((v4l2_std_id)0x00040000)
#define V4L2_STD_SECAM_H        ((v4l2_std_id)0x00080000)
#define V4L2_STD_SECAM_K        ((v4l2_std_id)0x00100000)
#define V4L2_STD_SECAM_K1       ((v4l2_std_id)0x00200000)
#define V4L2_STD_SECAM_L        ((v4l2_std_id)0x00400000)
#define V4L2_STD_SECAM_LC       ((v4l2_std_id)0x00800000)

/* ATSC/HDTV */
#define V4L2_STD_ATSC_8_VSB     ((v4l2_std_id)0x01000000)
#define V4L2_STD_ATSC_16_VSB    ((v4l2_std_id)0x02000000)

使用示例

​ 下图详细展示了用户空间到内核驱动的 ioctl 调用顺序与调用过程中所涉及到的文件及步骤顺序。(看不清可以下载或者在新标签页中打开查看)

在这里插入图片描述

下图详细展示了用户层使用v4l2框架编写一个摄像头采集程序的完整流程。

在这里插入图片描述

下面是一个可执行的完整摄像头采集程序示例(可以下载附件查看):
code.zip

个人博客:www.letcos.top

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值