摄像头v4l2的理解——摄像头相关数据的获取

培训机构学习总结

PS:

#include 

/usr/include/videodev2.h可以查看相对应的结构体
确定操作的设备文件是摄像头相关的

struct v4l2_capability cap;
if (ioctl(fd, VIDIOC_QUERYCAP, &cap) < 0)

printf("driver: %s\n", cap.driver);  // uvcvideo是linux下通用的usb摄像头驱动
printf("card: %s\n", cap.card);		//获取设备名
printf("bus info: %s\n", cap.bus_info);		//获取总线信息

if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) //判断摄像头是否可用
{
	printf("invalid camera");
	return 3;
}	

查询此设备文件对应的摄像头驱动支持的摄像头个数

struct v4l2_input inp;
	for (i = 0; ; i++)
	{
		inp.index = i;
		if (ioctl(fd, VIDIOC_ENUMINPUT, &inp) < 0)
			break;
		printf("input %d : %s\n", i, inp.name);
	}
	//如果支持多个摄像头,可通过ioctl的VIDIOC_S_INPUT指定使用第几个摄像头

查询摄像头支持的图像数据格式,分辨率,帧率

	struct v4l2_fmtdesc fmtd;	//存的是摄像头支持的传输格式
	struct v4l2_frmsizeenum  frmsize;	//存的是摄像头,对应的图片格式所支持的分辨率
	struct v4l2_frmivalenum  framival;	//存的时,对应的图片格式,分辨率所支持的帧率
	for (i = 0; ; i++)
	{
		fmtd.index = i;
		fmtd.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;		
		if (ioctl(fd, VIDIOC_ENUM_FMT, &fmtd) < 0)
			break;
		printf("fmt %d: %s\n", i, fmtd.description);
		// 查询这种图像数据格式下支持的分辨率
		for (j = 0; ; j++)
		{
			frmsize.index = j;
			frmsize.pixel_format = fmtd.pixelformat; 
			//fmtd.pixelformat 四字符代码(不知道是什么鬼,总之是识别图片格式)
			if (ioctl(fd, VIDIOC_ENUM_FRAMESIZES, &frmsize) < 0)
				break;
			printf("w = %d, h = %d\n", frmsize.discrete.width, frmsize.discrete.height);	

			//查询在这种图像数据格式下这种分辨率支持的帧率
			for (k = 0; ; k++)
			{
				framival.index = k;
				framival.pixel_format = fmtd.pixelformat;
				framival.width = frmsize.discrete.width;
				framival.height = frmsize.discrete.height;	
				if (ioctl(fd, VIDIOC_ENUM_FRAMEINTERVALS, &framival) < 0)
					break;
				//下面是帧率的获取
				printf("frame interval: %d, %d\n", framival.discrete.numerator, framival.discrete.denominator);	
			}
		}	
	}

源码


#include 
#include 
#include 
#include 

int main(void)
{
	int fd, i, j, k;

	fd = open("/dev/video0", O_RDWR);
	if (fd < 0)
	{
		perror("open dev");
		return 1;
	}

//   /dev/video? 这些设备文件是视频相关驱动产生的,摄像头只是视频设备中的一种,除此外还有硬件编解码的设备,图形加速等高设备。所以/dev/video?设备文件不一定是摄像头相关的设备文件.

	//检查打开的设备文件是不是摄像头的设备文件.
	
	struct v4l2_capability cap;
	if (ioctl(fd, VIDIOC_QUERYCAP, &cap) < 0)
	{
		perror("query cap");
		return 2;
	}
	printf("driver: %s\n", cap.driver);  // uvcvideo是linux下通用的usb摄像头驱动
	printf("card: %s\n", cap.card);
	printf("bus info: %s\n", cap.bus_info);

	if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE))
	{
		printf("invalid camera\n");
		return 3;
	}	
//
//查询此设备文件对应的摄像头驱动支持的摄像头个数
	struct v4l2_input inp;
	for (i = 0; ; i++)
	{
		inp.index = i;
		if (ioctl(fd, VIDIOC_ENUMINPUT, &inp) < 0)
			break;
		printf("input %d : %s\n", i, inp.name);
	}
	//如果支持多个摄像头,可通过ioctl的VIDIOC_S_INPUT指定使用第几个摄像头		

//查询摄像头支持的图像数据格式
	struct v4l2_fmtdesc fmtd;	//存的是摄像头支持的传输格式
	struct v4l2_frmsizeenum  frmsize;	//存的是摄像头,对应的图片格式所支持的分辨率
	struct v4l2_frmivalenum  framival;	//存的时,对应的图片格式,分辨率所支持的帧率
	for (i = 0; ; i++)
	{
		fmtd.index = i;
		fmtd.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;		
		if (ioctl(fd, VIDIOC_ENUM_FMT, &fmtd) < 0)
			break;
		printf("fmt %d: %s\n", i, fmtd.description);
		// 查询这种图像数据格式下支持的分辨率
		for (j = 0; ; j++)
		{
			frmsize.index = j;
			frmsize.pixel_format = fmtd.pixelformat; 
			//fmtd.pixelformat 四字符代码(不知道是什么鬼,总之是识别图片格式)
			if (ioctl(fd, VIDIOC_ENUM_FRAMESIZES, &frmsize) < 0)
				break;
			printf("w = %d, h = %d\n", frmsize.discrete.width, frmsize.discrete.height);	

			//查询在这种图像数据格式下这种分辨率支持的帧率
			for (k = 0; ; k++)
			{
				framival.index = k;
				framival.pixel_format = fmtd.pixelformat;
				framival.width = frmsize.discrete.width;
				framival.height = frmsize.discrete.height;	
				if (ioctl(fd, VIDIOC_ENUM_FRAMEINTERVALS, &framival) < 0)
					break;
				//下面是帧率的获取
				printf("frame interval: %d, %d\n", framival.discrete.numerator, framival.discrete.denominator);	
			}
		}	
	}

	close(fd);
	return 0;
}

你可能感兴趣的:(培训总结)