v4l2属性设置

来源:互联网 发布:跳跃网络次元大作战 编辑:程序博客网 时间:2024/06/16 07:06


ng_vid_drivers里边是什么东西

ng_vid_drivers_register 注册进这个ng_vid_register链表

搜索ng_vid_drivers_register会发现Drv0-v4l2.c用过它


 list_for_each (ng_vid_drivers)->open=v4l2_open

open  //打开设备

query_capablity   //查询它是不是视频设备

get_device_capablities()

/*contrals*/

这里先标记哪些contral能用,哪些ctrl不能用

八、从零写UVC驱动之实现设置属性(比如亮度)
1. 先看APP以确定需要实现哪些接口
xawtv.c
                     main   -->   grabber scan    -->    ng-vid-open   -->     list_for_each (ng_vid_drivers)->open
    grabber_scan
        ng_vid_open
            v4l2_driver.open // v4l2_open
                get_device_capabilities(h);
                    // 调用VIDIOC_QUERYCTRL ioctl确定是否支持某个属性
                    /* controls */
                    for (i = 0; i < MAX_CTRL; i++) {
                h->ctl[i].id = V4L2_CID_BASE+i;
                if (-1 == xioctl(h->fd, VIDIOC_QUERYCTRL, &h->ctl[i], EINVAL) ||
                   (h->ctl[i].flags & V4L2_CTRL_FLAG_DISABLED))
                   h->ctl[i].id = -1;
                    }
怎么去获得/设置属性?
看drv0-v4l2.c
可见这2个函数:
v4l2_read_attr  : VIDIOC_G_CTRL
v4l2_write_attr : VIDIOC_S_CTRL


所以: 视频驱动里要实现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(比如PU)
.selector = PU_BRIGHTNESS_CONTROL,   // 用于亮度
.index = 0,                       // 对应Processing Unit Descriptor的bmControls[0]
.size = 2,                       // 数据长度为2字节
.flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
| UVC_CONTROL_RESTORE,
},




 
2.2 我们的设备支持哪些属性
    这需要去看描述符, 比如 Processing Unit Descriptor的bmControls的值为7f 14
    可知BIT0为1,表示支持BRIGHTNESS
    
    在代码里:
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..
   
   // 设置这些struct uvc_control
   ctrl = entity->controls;
   for (...)
   {
    ctrl->entity = entity;
    ctrl->index = i;
}


        // 把uvc_control和uvc_control_info挂构
        uvc_ctrl_add_ctrl(dev, info);
            ctrl->info = 某个uvc_control_info数组项(同属于一个entity, index相同)


2.3 怎么去操作这些属性
    参考 uvc_query_v4l2_ctrl
    uvc_find_control
        找到一个uvc_control_mapping结构体: uvc_ctrl.c里有static struct uvc_control_mapping uvc_ctrl_mappings[] 
        {
        .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,// 数据类型
        },


         uvc_control_mapping结构体 用来更加细致地描述属性


    uvc_query_ctrl
        usb_control_msg




举例说明: 要设置亮度,怎么操作?
a. 根据PU的描述符的bmControls, 从它的bit0等于1知道它支持调节亮度
b. 在uvc_ctrls数组中根据entity和index找到这一项:
{
.entity = UVC_GUID_UVC_PROCESSING,
.selector = PU_BRIGHTNESS_CONTROL,
.index = 0,
.size = 2,
.flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
| UVC_CONTROL_RESTORE,
},


知道了:这个设备支持SET_CUR, GET_CUR, GET_MIN等
要设置时,可以向PU的selector发数据, 发的数据是2字节


c. 在uvc_ctrl_mappings数组
中根据ID找到对应的数组项
   从而知道了更加细致的信息,
   然后使用usb_control_msg读写数据
   


3. 怎么写代码?
实现3个ioctl: vidioc_queryctrl/vidioc_g_ctrl/vidioc_s_ctrl
vidioc_queryctrl : 发起USB控制传输获得亮度的最小值、最大值、默认值、步进值
vidioc_s_ctrl    : 把APP传入的亮度值通过USB传输发给硬件
vidioc_g_ctrl    : 发起USB传输获得当前亮度值


要点:数据发给谁?发给usb_device的
                          VideoControl Interface
                                    里面的Processing Unit 
                                            里面的PU_BRIGHTNESS_CONTROL
                  

0 0
原创粉丝点击