Linux中通过v4l2框架获取摄像头的能力的方法

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;
}

使用:

 

 


版权声明:本文为u010299133原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。