首先附上,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)