前言
对于摄像头的属性有亮度,曝光度等等…,那怎么去获得/设置这些属性呢,在应用层使用ioctl命令:VIDIOC_QUERYCTRL,VIDIOC_G_CTRL
,VIDIOC_S_CTRL来查询,获取,设置当前摄像头的属性,所以在底层驱动中中我们必须来实现这些函数的定义,该函数原型如下
int (*vidioc_queryctrl)(struct file *file, void *fh,struct v4l2_queryctrl *a);
int (*vidioc_g_ctrl)(struct file *file,void *fh,struct v4l2_control *a);
int (*vidioc_s_ctrl)(struct file *file,void *fh,struct v4l2_control *a);
我们之前说过USB摄像头一般会分为两个接口,一个是VC用于控制,一个是VS用于传输,在之前我们已经把摄像头图像显示出来了,所以对于VS这部分是完成,现在我们看到VC控制部分,对于VC中的Unit和terminal在代码中称为实体entity,在uvc_ctrl.c里数组static struct uvc_control_info uvc_ctrls[],这个数组里每一项都对应一个属性,这个数组里就定义了UVC规范所支持的所有属性,我们拿出一个属性定义来说明下:
{
.entity = UVC_GUID_UVC_PROCESSING,
.selector = UVC_PU_BRIGHTNESS_CONTROL,
.index = 0,
.size = 2,
.flags = UVC_CTRL_FLAG_SET_CUR
| UVC_CTRL_FLAG_GET_RANGE
| UVC_CTRL_FLAG_RESTORE,
},
我们设置亮度需要把数据发给硬件,发给VC中的哪个接口就由entity值来决定,显然上面该属性就是发给PU接口,PU接口就根据selector的值知道该属性是用来设置亮度的,index对应Process Unit Descriptor的bmControls[0],说明该属性是来设置亮度的,size表示发送的数据的大小,对于我们的设置支持哪些属性,这需要我们去看VideoControl Interface的自定义描述符(通过ls usb命令打印出),那在代码中我们怎么去设置这些属性呢,我们看到uvc_driver.c
uvc_drvier.c
uvc_ctrl_init_device
// 对于每一个entity(IT,PU,SU,OT等)
list_for_each_entry(entity, &dev->entities, list) {
// 取出bmControls
bmControls = ....
// 计算bmControls里位值为1的个数,就是支持的属性个数
ncontrols += hweight8(bmControls[i]);
// 为每一个属性分配一个struct uvc_control
entity->controls = kzalloc..