Including: hardware type, video frame format, video frame size, video frame rate, video brightness, contrast, color saturation
#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;
}