1. 打开设备
1)用非阻塞模式打开摄像头设备
int cameraFd;
cameraFd = open("/dev/video0", O_RDWR | O_NONBLOCK);
2)如果用阻塞模式打开摄像头设备,上述代码变为:
cameraFd = open("/dev/video0", O_RDWR);
关于阻塞模式和非阻塞模式:
应用程序能够使用阻塞模式或非阻塞模式打开视频设备,如果使用非阻塞模式调用视频设备,即使尚未捕获到信息,驱动依旧会把缓存(DQBUFF)里的东西返回给应用程序。
2. 查询视频设备的功能
控制命令VIDIOC_QUERYCAP
功能: 查询视频设备的功能;
参数说明:参数类型为V4L2的能力描述类型structv4l2_capability ;
返回值说明: 执行成功时,函数返回值为 0;函数执行成功后,structv4l2_capability 结构体变量中的返回当前视频设备所支持的功能;例如支持视频捕获功能V4L2_CAP_VIDEO_CAPTURE、V4L2_CAP_STREAMING等。
执行完VIDIOC_QUERYCAP命令后,cap变量中包含了该视频设备的能力信息,程序中通过检查cap中的设备能力信息来判断设备是否支持某项功能。
结构体:
描述设备能力结构struct v4l2_capability
struct v4l2_capability { __u8 driver[16]; // 驱动名字 __u8 card[32]; // 设备名字 __u8 bus_info[32]; // 设备在系统中的位置 __u32 version; // 驱动版本号 __u32 capabilities; // 设备支持的操作 __u32 reserved[4]; // 保留字段 }; |
capabilities 常用值:
V4L2_CAP_VIDEO_CAPTURE// 是否支持图像获取
例:显示设备信息
#include <errno.h> #define CLEAR(d) memset(&d, 0, sizeof(d)); /** * @brief query_cap * 查询摄像头参数及驱动信息:打印struct v4l2_capability * @param fd 摄像头文件描述符 * */ void query_cap(int fd) { struct v4l2_capability cap; CLEAR(cap); if(ioctl(fd,VIDIOC_QUERYCAP,&cap) < 0) //查询摄像头的功能 { perror("query_cap()"); //也是出错处理 exit(EXIT_FAILURE); } printf("===============Camera Info begin===============\n"); printf("Driver: %s \n",cap.driver); printf("Card: %s \n",cap.card); printf("BusInfo: %s \n",cap.bus_info); printf("Version: %d \n",cap.version); printf("Capabilities: 0x%x \n",cap.capabilities); printf("===============Camera Info end===============\n\n"); //printf("Device Cap: 0x%x \n",cap.device_caps); //printf("Reserved: 0x%x \n",cap.reserved); }
|
使用举例:
struct v4l2_capability cap; //这个设备的功能,比如是否是视频输入设备 /*查询设备的功能,*/ if (-1 == xioctl(fd, VIDIOC_QUERYCAP, &cap)) { if (EINVAL == errno) { fprintf(stderr, "%s is no V4L2 device\n", dev_name); exit(EXIT_FAILURE); } else { errno_exit("VIDIOC_QUERYCAP"); } } /*判断是否有捕获功能*/ if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) { fprintf(stderr, "%s is no video capture device\n", dev_name); exit(EXIT_FAILURE); } /*判断是否有启动设备功能*/ if (!(cap.capabilities & V4L2_CAP_STREAMING)) { fprintf(stderr, "%s does not support streaming i/o\n", dev_name); exit(EXIT_FAILURE); } |
2、获取视频设备支持的接口格式
1) 视频采集接口(video capture interface):这种应用的设备可以是高频头或者摄像头.V4L2的最初设计就是应用于这种功能的. --- 今天课程重点
2) 视频输出接口(video output interface):可以驱动计算机的外围视频图像设备--像可以输出电视信号格式的设备.
3)直接传输视频接口(video overlay interface):它的主要工作是把从视频采集设备采集过来的信号直接输出到输出设备之上,而不用经过系统的CPU.
4)视频间隔消隐信号接口(VBI interface):它可以使应用可以访问传输消隐期的视频信号.
5)收音机接口(radio interface):可用来处理从AM或FM高频头设备接收来的音频流.控制命令VIDIOC_ENUM_FMT
功能: 获取当前视频设备支持的接口格式。
参数说明:参数类型为V4L2的接口格式描述符类型 structv4l2_fmtdesc
返回值说明: 执行成功时,函数返回值为 0;struct v4l2_fmtdesc 结构体中的.pixelformat和 .description 成员返回当前视频设备所支持的接口格式;
结构体:
structv4l2_fmtdesc 视频格式描述符类型
/* * F O R M A T E N U M E R A T I O N视频格式描述符类型 */ struct v4l2_fmtdesc { __u32 index; // 要查询的格式序号,应用程序设置,从0开始,依次上升。 enum v4l2_buf_type type; // 帧类型,应用程序设置,Camera,则填写V4L2_BUF_TYPE_VIDEO_CAPTURE __u32 flags; // 是否为压缩格式,如果压缩的,则Driver 填写:V4L2_FMT_FLAG_COMPRESSED,否则为0 __u8 description[32]; // image format格式名称,如:”YUV 4:2:2 (YUYV)” //”RGB888” __u32 pixelformat; // 格式 __u32 reserved[4]; // 保留 };
|
这个结构通常用于枚举设备所支持的imageformat: VIDIOC_ENUM_FMT
struct v4l2_fmtdesc fmtdesc;
fmtdesc.index = 0;
fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
ret = ioctl(Handle, VIDIOC_ENUM_FMT, &fmtdesc);
使用ioctl VIDIOC_ENUM_FMT 依次询问,type为:V4L2_BUF_TYPE_VIDEO_CAPTURE。 index从0开始,依次增加,直到返回. Driver会填充结构体structv4l2_fmtdesc的其它内容,如果index超出范围,则返回-1。
enumv4l2_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, #if 1 /* Experimental */ V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY = 8, #endif V4L2_BUF_TYPE_PRIVATE = 0x80, }; |
1) typedef __u64 v4l2_std_id 视频设备支持的标准
typedef __u64 v4l2_std_id;
/* one bit for each */ #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_PA |