V4L2学习笔记

本文详细介绍了Linux内核中的v4l2模块,包括如何依赖其内核函数实现设备驱动,如`v4l2_ioctl_ops`结构和常用操作如查询设备能力、格式化等。通过mvx_v4l2_fops和ioctl操作的实例,深入讲解了驱动开发中必备的知识点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

首先附上,Linux内核网站:
入口

v4l2非常棒的一篇文章
入口

内核代码查看:
入口

一个博客文档:
入口
https://lwn.net/Articles/204545/

别人整理

关于linux内核头函数:
/usr/src/xxx

系列文
在这里插入图片描述
在其内部有media文件夹,里面含有v4l2有关的内核函数。
在这里插入图片描述
我们的设别驱动都是要依赖这些内核函数,但是平时这些内核函数是不存在的,只有你把设备挂载后才会出现:

在这里插入图片描述
如果你要实现一个v4l2驱动,只要简单进行对下属函数重写就可以了:

struct v4l2_ioctl_ops {
	/* ioctl callbacks */

	/* VIDIOC_QUERYCAP handler */
	int (*vidioc_querycap)(struct file *file, void *fh,
			       struct v4l2_capability *cap);

	/* VIDIOC_ENUM_FMT handlers */
	int (*vidioc_enum_fmt_vid_cap)(struct file *file, void *fh,
				       struct v4l2_fmtdesc *f);
	int (*vidioc_enum_fmt_vid_overlay)(struct file *file, void *fh,
					   struct v4l2_fmtdesc *f);
	int (*vidioc_enum_fmt_vid_out)(struct file *file, void *fh,
				       struct v4l2_fmtdesc *f);
	int (*vidioc_enum_fmt_vid_cap_mplane)(struct file *file, void *fh,
					      struct v4l2_fmtdesc *f);

};

static const struct v4l2_file_operations mvx_v4l2_fops = {
	.owner          = THIS_MODULE,
	.open           = mvx_v4l2_open,
	.release        = mvx_v4l2_release,
	.poll           = mvx_v4l2_poll,
	.unlocked_ioctl = video_ioctl2,
	.mmap           = mvx_v4l2_mmap
};

static const struct v4l2_ioctl_ops mvx_v4l2_ioctl_ops = {
	.vidioc_querycap                = mvx_v4l2_vidioc_querycap,
	.vidioc_enum_fmt_vid_cap        = mvx_v4l2_vidioc_enum_fmt_vid_cap,
	.vidioc_enum_fmt_vid_out        = mvx_v4l2_vidioc_enum_fmt_vid_out,
	.vidioc_enum_fmt_vid_cap_mplane = mvx_v4l2_vidioc_enum_fmt_vid_cap,
	.vidioc_enum_fmt_vid_out_mplane = mvx_v4l2_vidioc_enum_fmt_vid_out,
	.vidioc_enum_framesizes         = mvx_v4l2_vidioc_enum_framesizes,
	.vidioc_g_fmt_vid_cap           = mvx_v4l2_vidioc_g_fmt_vid_cap,
	.vidioc_g_fmt_vid_cap_mplane    = mvx_v4l2_vidioc_g_fmt_vid_cap,
	.vidioc_g_fmt_vid_out           = mvx_v4l2_vidioc_g_fmt_vid_out,
	.vidioc_g_fmt_vid_out_mplane    = mvx_v4l2_vidioc_g_fmt_vid_out,
	.vidioc_s_fmt_vid_cap           = mvx_v4l2_vidioc_s_fmt_vid_cap,
	.vidioc_s_fmt_vid_cap_mplane    = mvx_v4l2_vidioc_s_fmt_vid_cap,
	.vidioc_s_fmt_vid_out           = mvx_v4l2_vidioc_s_fmt_vid_out,
	.vidioc_s_fmt_vid_out_mplane    = mvx_v4l2_vidioc_s_fmt_vid_out,
	.vidioc_try_fmt_vid_cap         = mvx_v4l2_vidioc_try_fmt_vid_cap,
	.vidioc_try_fmt_vid_cap_mplane  = mvx_v4l2_vidioc_try_fmt_vid_cap,
	.vidioc_try_fmt_vid_out         = mvx_v4l2_vidioc_try_fmt_vid_out,
	.vidioc_try_fmt_vid_out_mplane  = mvx_v4l2_vidioc_try_fmt_vid_out,
	.vidioc_g_crop                  = mvx_v4l2_vidioc_g_crop,
	.vidioc_streamon                = mvx_v4l2_vidioc_streamon,
	.vidioc_streamoff               = mvx_v4l2_vidioc_streamoff,
	.vidioc_encoder_cmd             = mvx_v4l2_vidioc_encoder_cmd,
	.vidioc_try_encoder_cmd         = mvx_v4l2_vidioc_try_encoder_cmd,
	.vidioc_decoder_cmd             = mvx_v4l2_vidioc_decoder_cmd,
	.vidioc_try_decoder_cmd         = mvx_v4l2_vidioc_try_decoder_cmd,
	.vidioc_reqbufs                 = mvx_v4l2_vidioc_reqbufs,
	.vidioc_create_bufs             = mvx_v4l2_vidioc_create_bufs,
	.vidioc_querybuf                = mvx_v4l2_vidioc_querybuf,
	.vidioc_qbuf                    = mvx_v4l2_vidioc_qbuf,
	.vidioc_dqbuf                   = mvx_v4l2_vidioc_dqbuf,
	.vidioc_subscribe_event         = mvx_v4l2_vidioc_subscribe_event,
	.vidioc_unsubscribe_event       = v4l2_event_unsubscribe,
	.vidioc_default                 = mvx_v4l2_vidioc_default
};

1、在Linux/videodev2.h中定义了枚举类型和关键结构体,这些都是对app用户而言的:

{
	V4L2_FIELD_ANY           = 0, /* driver can choose from none,top, bottom, interlaced depending on whatever it thinksis 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 */
};

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,
	V4L2_BUF_TYPE_META_OUTPUT	   = 14,
	/* Deprecated, do not use */
	V4L2_BUF_TYPE_PRIVATE              = 0x80,
};

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

struct v4l2_capability {
	__u8	driver[16];
	__u8	card[32];
	__u8	bus_info[32];
	__u32   version;
	__u32	capabilities;
	__u32	device_caps;
	__u32	reserved[3];
};
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_*) */
	union {
		/* enum v4l2_ycbcr_encoding */
		__u32			ycbcr_enc;
		/* enum v4l2_hsv_encoding */
		__u32			hsv_enc;
	};
	__u32			quantization;	/* enum v4l2_quantization */
	__u32			xfer_func;	/* enum v4l2_xfer_func */
};
/* RGB formats */
#define V4L2_PIX_FMT_RGB332  v4l2_fourcc('R', 'G', 'B', '1') /*  8  RGB-3-3-2     */
#define V4L2_PIX_FMT_RGB444  v4l2_fourcc('R', '4', '4', '4') /* 16  xxxxrrrr ggggbbbb */
#define V4L2_PIX_FMT_ARGB444 v4l2_fourcc('A', 'R', '1', '2') /* 16  aaaarrrr ggggbbbb */
#define V4L2_PIX_FMT_XRGB444 v4l2_fourcc('X', 'R', '1', '2') /* 16  xxxxrrrr ggggbbbb */
#define V4L2_PIX_FMT_RGBA444 v4l2_fourcc('R', 'A', '1', '2') /* 16  rrrrgggg bbbbaaaa */
#define V4L2_PIX_FMT_RGBX444 v4l2_fourcc('R', 'X', '1', '2') /* 16  rrrrgggg bbbbxxxx */
#define V4L2_PIX_FMT_ABGR444 v4l2_fourcc('A', 'B', '1', '2') /* 16  aaaabbbb ggggrrrr */
#define V4L2_PIX_FMT_XBGR444 v4l2_fourcc('X', 'B', '1', '2') /* 16  xxxxbbbb ggggrrrr */

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];
};
struct v4l2_plane {
	__u32			bytesused;
	__u32			length;
	union {
		__u32		mem_offset;
		unsigned long	userptr;
		__s32		fd;
	} m;
	__u32			data_offset;
	__u32			reserved[11];
};
struct v4l2_buffer {
	__u32			index;
	__u32			type;
	__u32			bytesused;
	__u32			flags;
	__u32			field;
	struct timeval		timestamp;
	struct v4l2_timecode	timecode;
	__u32			sequence;

	/* memory location */
	__u32			memory;
	union {
		__u32           offset;
		unsigned long   userptr;
		struct v4l2_plane *planes;
		__s32		fd;
	} m;
	__u32			length;
	__u32			reserved2;
	union {
		__s32		request_fd;
		__u32		reserved;
	};
};
struct v4l2_output {
	__u32	     index;		/*  Which output */
	__u8	     name[32];		/*  Label */
	__u32	     type;		/*  Type of output */
	__u32	     audioset;		/*  Associated audios (bitfield) */
	__u32	     modulator;         /*  Associated modulator */
	v4l2_std_id  std;
	__u32	     capabilities;
	__u32	     reserved[3];
};

#define VIDIOC_QUERYCAP		 _IOR('V',  0, struct v4l2_capability)
#define VIDIOC_ENUM_FMT         _IOWR('V',  2, struct v4l2_fmtdesc)
#define VIDIOC_G_FMT		_IOWR('V',  4, struct v4l2_format)
#define VIDIOC_S_FMT		_IOWR('V',  5, struct v4l2_format)
#define VIDIOC_REQBUFS		_IOWR('V',  8, struct v4l2_requestbuffers)
#define VIDIOC_QUERYBUF		_IOWR('V',  9, struct v4l2_buffer)
#define VIDIOC_G_FBUF		 _IOR('V', 10, struct v4l2_framebuffer)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值