c 查询v4l2摄像头 各种参数

包括: 硬件类型,视频帧格式,视频帧尺寸,视频帧率,视频亮度,对比度,色饱和度


#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/videodev2.h>


#include <string.h>
#include <sys/mman.h>
#include <sys/time.h>

int main(void) {
	int fd = open("/dev/video0", O_RDWR);
	puts("----------------查询摄像头是否支持v4l2协议--------------");
	struct v4l2_capability {  // VIDIOC_QUERYCAP
		__u8	driver[16];     //uvc   必须是UVC才支持v4l2
		__u8	card[32];
		__u8	bus_info[32];
		__u32   version;
		__u32	capabilities;    //功能
		__u32	device_caps;
		__u32	reserved[3];
	};
	struct v4l2_capability  cap;
	int t = ioctl(fd, VIDIOC_QUERYCAP, &cap);
	if (t < 0) {
		puts("读卡错误");
		exit(-1);
	}
	printf("是否是UVC(开头必须是UVC):%s\n", cap.driver);
	printf("%s\n", cap.card);
	printf("%s\n", cap.bus_info);
	printf("%d\n", cap.version);
	printf("是否是视频输入卡(尾数必须是1):%x\n", cap.capabilities);       //84a00001   位数必须是1 , 1代表视频输入卡 
	printf("%x\n", cap.device_caps);        //4200001
	printf("%d\n", cap.reserved[0]);
	printf("%d\n", cap.reserved[1]);
	printf("%d\n", cap.reserved[2]);
	
	puts("--------------查询摄像头支持的多种视频格式-------------------------------------");
	struct v4l2_fmtdesc {         //VIDIOC_ENUM_FMT
		__u32		    index;             /* Format number      */
		__u32		    type;              /* enum v4l2_buf_type */
		__u32               flags;
		__u8		    description[32];   /* Description string */
		__u32		    pixelformat;       /* Format fourcc      */
		__u32		    mbus_code;		/* Media bus code    */
		__u32		    reserved[3];
	}fmtdesc;
	int n1=0;
	int t1;
	do{      //先输入硬件参数,再查询结果
	    fmtdesc.index=n1;    //从0输入index的值,开始查询,本机index=0,1    如有index  都是表示struct可以循环查询的
	    fmtdesc.type=1;
	    t1=ioctl(fd,VIDIOC_ENUM_FMT,&fmtdesc);
	    if(t1<0){
		    // puts("fmtdesc error");
			 break;
	    }
	    printf("%s\n",fmtdesc.description);  //0:yuv422,1:mjpg
	    n1++;
    }while(t1>=0);
		
	puts("-------------------查询摄像头支持的最大像素,视频格式,最大帧字节数-------------------------");
	
	struct v4l2_format {
		__u32	 type;
		union {
		//	struct v4l2_pix_format		pix;     /* V4L2_BUF_TYPE_VIDEO_CAPTURE */
			struct v4l2_pix_format {
				__u32			width;
				__u32			height;
				__u32			pixelformat;
				__u32			field;		/* enum v4l2_field */
				__u32			bytesperline;	/* for padding, zero if unused */
				__u32			sizeimage;
				__u32			colorspace;	/* enum v4l2_colorspace */
				__u32			priv;		/* private data, depends on pixelformat */
				union {
					/* enum v4l2_ycbcr_encoding */
					__u32			ycbcr_enc;
					/* enum v4l2_hsv_encoding */
					__u32			hsv_enc;
				};
				__u32			quantization;	/* enum v4l2_quantization */
				__u32			xfer_func;	/* enum v4l2_xfer_func */
			}pix;
			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;
	}format;
	format.type=1;          //摄像头都是等于1
	int t3=ioctl(fd,VIDIOC_G_FMT,&format);
	if(t3<0){
		puts("format error");
		exit(-1);
	}
	printf("最大宽度:%d\n",format.fmt.pix.width);               //2560   支持最大宽度      
	printf("最大高度:%d\n",format.fmt.pix.height);              //1440   支持图像的最高宽度
	printf("帧格式:%x\n",format.fmt.pix.pixelformat);        //v4l2_fourcc值 47504a4d    4d=M 4a=J  50=P 47=G   16进制小序排列(反向)
                                                              //acsii 码
	printf("%d\n",format.fmt.pix.field);              //1=V4L2_FIELD_NONE
	printf("最大帧字节数:%d\n",format.fmt.pix.sizeimage);          //7372800=2560*1440*16/8    每帧支持最大字节数
	
	puts("--------------------查询摄像头支持的各种屏幕尺寸(像素)大小------------------------------------");
	struct v4l2_frmsizeenum {
		__u32			index;		/* Frame size number */
		__u32			pixel_format;	/* Pixel format */
		__u32			type;		/* Frame size type the device supports. */
		
		union {					/* Frame size */
		  //	struct v4l2_frmsize_discrete	discrete;
			struct v4l2_frmsize_discrete {
				__u32			width;		/* Frame width [pixel] */
				__u32			height;		/* Frame height [pixel] */
			}discrete;

			struct v4l2_frmsize_stepwise	stepwise;
		};
		
		__u32   reserved[2];			/* Reserved space for future use */
	}frmsize;
	
	int t4;
	int n4=0;
	do{
         frmsize.index=n4;
	     frmsize.pixel_format=0x47504a4d;     // fourcc 视频格式 16进制
	
	     t4=ioctl(fd,VIDIOC_ENUM_FRAMESIZES,&frmsize);
	     if(t4<0){
			  break;
     	}
	    printf("width:%d\n",frmsize.discrete.width);
    	printf("heigth:%d\n",frmsize.discrete.height);
	    n4++;
	    puts("********************");
	}while(t4>=0);
	puts("-----------------查询支持帧率--------------------");   //VIDIOC_ENUM_FRAMEINTERVALS
	
	struct v4l2_frmivalenum {
		__u32			index;		/* Frame format index */
		__u32			pixel_format;	/* Pixel format */
		__u32			width;		/* Frame width */
		__u32			height;		/* Frame height */
		__u32			type;		/* Frame interval type the device supports. */
		
		union {					/* Frame interval */
			//struct v4l2_fract		discrete;
			struct v4l2_fract {
				__u32   numerator;          //分子
				__u32   denominator;          //分母
			}discrete;
			struct v4l2_frmival_stepwise	stepwise;
		};
		
		__u32	reserved[2];			/* Reserved space for future use */
	}fra_rate;
	
	int t5;
	int n5=0;
	do{
		fra_rate.index=n5;
		fra_rate.pixel_format=v4l2_fourcc('M','J','P','G');           //0x47504a4d=v4l2_fourcc('M','J','P','G);
		fra_rate.width=1280;
		fra_rate.height=720;
		t5=ioctl(fd,VIDIOC_ENUM_FRAMEINTERVALS,&fra_rate);
		if(t5<0){
		//	puts("rate error");
			break;
		}
		printf("帧率:%d\n",(fra_rate.discrete.denominator/fra_rate.discrete.numerator));
	    n5++;
	
	}while(t5>=0);
	
	puts("----------------查找v4l2 设备--------------------");
	
	struct v4l2_input {       // VIDIOC_ENUMINPUT
		__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];
	}v4input;
	
	int t6;
	int n6=0;
	do{
		v4input.index=n6;
		t6=ioctl(fd,VIDIOC_ENUMINPUT,&v4input);
		if(t6<0){
		  //	puts("input error");
			break;
		}
		printf("%s\n",v4input.name);
		printf("%d\n",v4input.std);
		n6++;
	}while(t6>=0);
	puts("--------------查询亮度、对比度、色调、饱和度---------------");
	/*  Used in the VIDIOC_QUERYCTRL ioctl for querying controls */
	struct v4l2_queryctrl {
		__u32		     id;
		__u32		     type;	/* enum v4l2_ctrl_type */
		__u8		     name[32];	/* Whatever */
		__s32		     minimum;	/* Note signedness */
		__s32		     maximum;
		__s32		     step;      //调节步长
		__s32		     default_value; //默认值
		__u32                flags;
		__u32		     reserved[2];
	}v4ctrl;
	
//id = V4L2_CID_BASE;(0x00980000|0x900)    定义在v4l2-controls.h
//id < V4L2_CID_LASTP1;(0x00980000|0x900)+43
	for(v4ctrl.id=(0x00980000|0x900);v4ctrl.id<(0x00980000|0x900)+43;v4ctrl.id++){

	
	int t7=ioctl(fd,VIDIOC_QUERYCTRL,&v4ctrl);
	if(t7<0){
	//	puts("ctrl error");
		break;
	}
	printf("%s\n",v4ctrl.name);
	printf("%d\n",v4ctrl.maximum);     //调节最大值
	printf("%d\n",v4ctrl.minimum);     //调节最小值
	printf("%d\n",v4ctrl.step);         //调节步长
	printf("%d\n",v4ctrl.default_value);  //默认值
	
	}
	
	puts("over");
	return 0;
}

猜你喜欢

转载自blog.csdn.net/m0_59802969/article/details/134471728