1. 在视频驱动程序中设置属性主要涉及3个ioctl :
VIDIOC_QUERYCTRL
VIDIOC_G_CTRL
VIDIOC_S_CTRL
2. 硬件上怎么设置属性呢?
2.1 UVC规划定义了那些属性:定义在uvc_ctrl.c里面的数组
static struct uvc_control_info uvc_ctrls[] = {{.entity = UVC_GUID_UVC_PROCESSING, //属于哪一个entity .selector = UVC_PU_BRIGHTNESS_CONTROL,//用于亮度.index = 0,// 对应Processing Unit Descriptor 的bmControls[0].size = 2,//数据长度2个字节.flags = UVC_CTRL_FLAG_SET_CUR| UVC_CTRL_FLAG_GET_RANGE| UVC_CTRL_FLAG_RESTORE,},
}
2.2 设备支持哪些属性呢
这需要具体去看设备描述符,比如 Processing Unit Descriptor 的bmControls值为7f 14
可知BIT0 为1 表示支持BRIGHTNESS
在代码中
uvc_ctrl_init_device(dev)
对于每一个entity(IT,PU,SU,OT等)
list_for_each_entry(entity, &dev->entities, list)
分别提取对应的控制集(bmControls)以及控制的大小(bControlSize)
if (UVC_ENTITY_TYPE(entity) == UVC_VC_EXTENSION_UNIT) {bmControls = entity->extension.bmControls;bControlSize = entity->extension.bControlSize;} else if (UVC_ENTITY_TYPE(entity) == UVC_VC_PROCESSING_UNIT) {bmControls = entity->processing.bmControls;bControlSize = entity->processing.bControlSize;
计算bmControls 里面1 的个数 也就是支持的属性个数
ncontrols = memweight(bmControls, bControlSize);
为每一个属性分配一个struct uvc_control
entity->controls = kcalloc(ncontrols, sizeof(*ctrl),GFP_KERNEL);
设置这些struct uvc_control
ctrl = entity->controls;for (i = 0; i < bControlSize * 8; ++i) {if (uvc_test_bit(bmControls, i) == 0)continue;ctrl->entity = entity;ctrl->index = i;uvc_ctrl_init_ctrl(dev, ctrl);ctrl++;}
2.3 怎么去操控这些属性呢
参考
uvc_ioctl_queryctrl
---->uvc_query_v4l2_ctrl(chain, qc);
------>uvc_find_control
关于结构体 uvc_control_mapping 用来更加细致的描述 属性
struct uvc_control_mapping {struct list_head list;struct list_head ev_subs;__u32 id; __u8 name[32];__u8 entity[16];__u8 selector;__u8 size;__u8 offset;enum v4l2_ctrl_type v4l2_type;__u32 data_type;struct uvc_menu_info *menu_info;__u32 menu_count;__u32 master_id;__s32 master_manual;__u32 slave_ids[2];__s32 (*get) (struct uvc_control_mapping *mapping, __u8 query,const __u8 *data);void (*set) (struct uvc_control_mapping *mapping, __s32 value,__u8 *data);
};
例如
{.id = V4L2_CID_BRIGHTNESS, // APP根据ID来找到对应的属性.name = "Brightness",.entity = UVC_GUID_UVC_PROCESSING, // 属于哪了个entity(比如PU).selector = PU_BRIGHTNESS_CONTROL, // 用于亮度.size = 16, // 数据占多少位.offset = 0, // 从哪位开始.v4l2_type = V4L2_CTRL_TYPE_INTEGER, // 属性类别.data_type = UVC_CTRL_DATA_TYPE_SIGNED,// 数据类型},