v4l2(video for linux two)是Linux中内核提供给应用层访问音视频驱动的统一接口。v4l2中获取摄像头的能力的是通过ioctl函数的VIDIOC_QUERYCAP命令获取,并且获得的能力使用结构体v4l2_capability描述。
v4l2能力藐视结构体v4l2_capability的具体介绍如下:
定义文件:
/kernel/include/uapi/linux/videodev2.h
结构体原型:
struct v4l2_capability {
__u8 driver[16]; //name of the driver module
__u8 card[32]; //name of the card
__u8 bus_info[32];//name of the bus
__u32 version; //kernel version
__u32 capabilities;//capabilities of the physical device as a whole
__u32 device_caps; //capabilities aeccessed via this particular device
__u32 reserved[3];
};
其中capabilities的值各个位所对应的功能:
/* Values for 'capabilities' field */
#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 */
#define V4L2_CAP_SLICED_VBI_CAPTURE 0x00000040 /* Is a sliced VBI capture device */
#define V4L2_CAP_SLICED_VBI_OUTPUT 0x00000080 /* Is a sliced VBI output device */
#define V4L2_CAP_RDS_CAPTURE 0x00000100 /* RDS data capture */
#define V4L2_CAP_VIDEO_OUTPUT_OVERLAY 0x00000200 /* Can do video output overlay */
#define V4L2_CAP_HW_FREQ_SEEK 0x00000400 /* Can do hardware frequency seek */
#define V4L2_CAP_RDS_OUTPUT 0x00000800 /* Is an RDS encoder */
/* Is a video capture device that supports multiplanar formats */
#define V4L2_CAP_VIDEO_CAPTURE_MPLANE 0x00001000
/* Is a video output device that supports multiplanar formats */
#define V4L2_CAP_VIDEO_OUTPUT_MPLANE 0x00002000
/* Is a video mem-to-mem device that supports multiplanar formats */
#define V4L2_CAP_VIDEO_M2M_MPLANE 0x00004000
/* Is a video mem-to-mem device */
#define V4L2_CAP_VIDEO_M2M 0x00008000
#define V4L2_CAP_TUNER 0x00010000 /* has a tuner */
#define V4L2_CAP_AUDIO 0x00020000 /* has audio support */
#define V4L2_CAP_RADIO 0x00040000 /* is a radio device */
#define V4L2_CAP_MODULATOR 0x00080000 /* has a modulator */
#define V4L2_CAP_READWRITE 0x01000000 /* read/write systemcalls */
#define V4L2_CAP_ASYNCIO 0x02000000 /* async I/O */
#define V4L2_CAP_STREAMING 0x04000000 /* streaming I/O ioctls */
#define V4L2_CAP_DEVICE_CAPS 0x80000000 /* sets device capabilities field */
源代码:
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <linux/videodev2.h>
/*VIDIOC_QUERYCAP ---- struct v4l2_capability*/
/*
header path:./kernel/include/uapi/linux/videodev2.h
struct v4l2_capability {
__u8 driver[16]; //name of the driver module
__u8 card[32]; //name of the card
__u8 bus_info[32];//name of the bus
__u32 version; //kernel version
__u32 capabilities;//capabilities of the physical device as a whole
__u32 device_caps; //capabilities aeccessed via this particular device
__u32 reserved[3];
};
*/
int main(int argc, char *argv[])
{
if(argc < 2){
printf("this process arg error\n");
return -1;
}
printf("camera device:%s\n", argv[1]);
int cam_fd = open(argv[1], O_RDWR);
if(cam_fd < 0){
printf("open the camera device:%s is error: %s\n", argv[1], strerror(errno));
return -2;
}
struct v4l2_capability cap;
if(ioctl(cam_fd, VIDIOC_QUERYCAP, &cap) == -1){
printf("Unable query the ability of the device %s\n ", argv[1]);
return -3;
}
printf("driver:\t%s\n", cap.driver);
printf("card:\t%s\n", cap.card);
printf("bus_info:\t%s\n", cap.bus_info);
printf("version:\t%d\n", cap.version);
printf("capability:\t%x\n", cap.capabilities);
if((cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) == V4L2_CAP_VIDEO_CAPTURE){
printf("the device %s is support capture\n", argv[1]);
}else{
printf("the device %s is not support capture\n", argv[1]);
}
if((cap.capabilities & V4L2_CAP_STREAMING) == V4L2_CAP_STREAMING){
printf("the device %s is support streaming\n", argv[1]);
}else{
printf("the device %s is not support streaming\n", argv[1]);
}
printf("device_caps:\t%x\n", cap.device_caps);
close(cam_fd);
return 0;
}
使用:
