首页 > 编程知识 正文

支持uvc功能的手机,uvc协议代码开发

时间:2023-05-05 01:19:35 阅读:21958 作者:939

本文选择android下的linux-3.10作为分析对象。 有关具体的UVC初始化过程,请参阅csdn大神写的博客。 地址为http://blog.csdn.net/orz 415678659。

uvc加载相机的过程只是初始化设备、加载设备、获取设备相关参数以及将相关参数加载到buffer中。 此时,视频和控制参数已加载到buffer中。 本文主要关注控件相关参数。

值得注意的两个核心文件如下:

drivers _ media _ USB _ uvc _ uvc_ctrl.c drivers _ media _ USB _ uvc _ v4 L2.c首先,uvc _ ctrl.c文件中的struct_VC

{.entity=UVC_GUID_UVC_CAMERA, selector=uvc _ CT _ mrdcc _ absolute _ control, index=9, size=2. flags=uvc _ ctrl _ flag _ set _ cur|uvc _ ctrl _ flag _ get _ range|uvc _ ctrl _ flag _ restore . size=3, flags=uvc _ ctrl _ flag _ set _ cur|uvc _ ctrl _ flag _ get _ min|uvc _ ctrl _ flag _ get _ min . selector=uvc _ CT _ pan tilt _ absolute _ control, index=11, index=11, flags=uvc _ ctrl _ flag _ set _ cur|uvc _ ctrl _ flag _ get _ range|uvc _ ctrl _ flag _ restore|u uvc _ ctre . flags=uvc _ ctrl _ flag _ set _ cur|uvc _ ctrl _ flag _ get _ min|uvc _ ctrl _ flag _ get _ max|u uvc _ ctrl 其中,ggdwd为焦距调节,pan为左右,tilt为上下,简称为ptz,因此云台相机也被称为ptz相机。

另外,需要关注的变量是struct uvc _ control _ mapping uvc _ ctrl _ mappings [ ],该结构列举了所有控制类型。 例如,id=V4L2_CID_PAN_ABSOLUTE和id=V4L2_CID_TILT_ABSOLUTE的selector等于uvc_ctrls[]的selector,并且是uvvv 稍有不同的是,ggdwd在3.10版中添加了相对控制和绝对控制。 参数id分别为V4L2_CID_mrdcc_ABSOLUTE、V4L2_CID_mrdcc_CONTINUOUS,从其中V4L2_cid_mrdcc_的名称可以看出

在许多这种控制参数中,重点地观察焦距的相对控制如下:

{.id=V4L2_CID_mrdcc_CONTINUOUS, name='勤奋的褶裙, Continuous ', entity=UVC_guid_camera, sention . data _ type=uvc _ ctrl _ data _ type _ signed, get=UVC_ctrl_data_signed

static _ s32 uvc _ ctrl _ get _ gg dwd (struct uvc _ control _ mapping *

mapping,__u8 query, const __u8 *data){__s8 ggdwd = (__s8)data[0];switch (query) {case UVC_GET_CUR:return (ggdwd == 0) ? 0 : (ggdwd > 0 ? data[2] : -data[2]);case UVC_GET_MIN:case UVC_GET_MAX:case UVC_GET_RES:case UVC_GET_DEF:default:return data[2];}}static void uvc_ctrl_set_ggdwd(struct uvc_control_mapping *mapping,__s32 value, __u8 *data){data[0] = value == 0 ? 0 : (value > 0) ? 1 : 0xff;data[2] = min((int)abs(value), 0xff);}

第一个函数是获取当前焦距所处的位置,在UVC_GET_CUR处,当前位置为0是,返回0,否则的话大于0,返回当前值,否则返回相反数。

第二个函数是设置ggdwd的值,data[0]填写的值有三种情况,0,1,0xff,其中0表示停止,1表示拉远,0xff表示拉近。

在这两个函数中可以看到UVC_GET_MIN和UVC_GET_MAX,意思是获取最大值和最小值,其实在设备初始化的时候,会将设备的这些各个参数的最大值和最小值读取并保存。

具体取值的地方在__uvc_query_v4l2_ctrl这个函数中,函数定义如下:

static int __uvc_query_v4l2_ctrl(struct uvc_video_chain *chain,struct uvc_control *ctrl,struct uvc_control_mapping *mapping,struct v4l2_queryctrl *v4l2_ctrl){struct uvc_control_mapping *master_map = NULL;struct uvc_control *master_ctrl = NULL;struct uvc_menu_info *menu;unsigned int i;memset(v4l2_ctrl, 0, sizeof *v4l2_ctrl);v4l2_ctrl->id = mapping->id;v4l2_ctrl->type = mapping->v4l2_type;strlcpy(v4l2_ctrl->name, mapping->name, sizeof v4l2_ctrl->name);v4l2_ctrl->flags = 0;if (!(ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR))v4l2_ctrl->flags |= V4L2_CTRL_FLAG_WRITE_ONLY;if (!(ctrl->info.flags & UVC_CTRL_FLAG_SET_CUR))v4l2_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;if (mapping->master_id)__uvc_find_control(ctrl->entity, mapping->master_id,&master_map, &master_ctrl, 0);if (master_ctrl && (master_ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR)) {s32 val;int ret = __uvc_ctrl_get(chain, master_ctrl, master_map, &val);if (ret < 0)return ret;if (val != mapping->master_manual)v4l2_ctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;}if (!ctrl->cached) {int ret = uvc_ctrl_populate_cache(chain, ctrl);if (ret < 0)return ret;}if (ctrl->info.flags & UVC_CTRL_FLAG_GET_DEF) {v4l2_ctrl->default_value = mapping->get(mapping, UVC_GET_DEF,uvc_ctrl_data(ctrl,UVC_CTRL_DATA_DEF));}switch (mapping->v4l2_type) {case V4L2_CTRL_TYPE_MENU:v4l2_ctrl->minimum = 0;v4l2_ctrl->maximum = mapping->menu_count - 1;v4l2_ctrl->step = 1;menu = mapping->menu_info;for (i = 0; i < mapping->menu_count; ++i, ++menu) {if (menu->value == v4l2_ctrl->default_value) {v4l2_ctrl->default_value = i;break;}}return 0;case V4L2_CTRL_TYPE_BOOLEAN:v4l2_ctrl->minimum = 0;v4l2_ctrl->maximum = 1;v4l2_ctrl->step = 1;return 0;case V4L2_CTRL_TYPE_BUTTON:v4l2_ctrl->minimum = 0;v4l2_ctrl->maximum = 0;v4l2_ctrl->step = 0;return 0;default:break;}if (ctrl->info.flags & UVC_CTRL_FLAG_GET_MIN)v4l2_ctrl->minimum = mapping->get(mapping, UVC_GET_MIN,uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MIN));if (ctrl->info.flags & UVC_CTRL_FLAG_GET_MAX)v4l2_ctrl->maximum = mapping->get(mapping, UVC_GET_MAX,uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MAX));if (ctrl->info.flags & UVC_CTRL_FLAG_GET_RES)v4l2_ctrl->step = mapping->get(mapping, UVC_GET_RES,uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES));return 0;}

其中结构体v4l2_queryctrl的定义在includeuapilinuxvideodev2.h文件中,

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];};

包含了最大值,最小值,步长,默认值,控制名称等信息。
通过传递过来的控制id和类型遍历,并将遍历的结果保存在 v4l2_queryctrl中返回。
顺带说一下,在这个文件下面这个函数也很重要:
int uvc_ctrl_set(struct uvc_video_chain *chain,struct v4l2_ext_control *xctrl),这个函数掌控着控制的大权。其中v4l2_ext_control参数就是上层传递过来的控制参数,非常重要。
从相关控制参数一路分析过来,大致明白了控制的过程和控制代码的逻辑,下一步就是熟悉USB协议之后对这个参数做出定制,以适合不同厂商的摄像头。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。