美文网首页
[Camera]v4l2用户空间

[Camera]v4l2用户空间

作者: Letcos | 来源:发表于2020-02-08 16:20 被阅读0次
参考:
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

相关文章

网友评论

      本文标题:[Camera]v4l2用户空间

      本文链接:https://www.haomeiwen.com/subject/tmmixhtx.html