一起走进UVC XU扩展协议

目录

前言 

UVC 扩展单元控制请求

调试工具介绍

PC平台如何接入

Windows DS API说明

PC代码接入

Android平台如何接入

  接入误区

Android代码接入

总结


前言 

         最近项目有一个需求,需要基于 UVC XU 扩展协议实现控灯功能。在网上搜索了一些资料后发现,PC 平台的相关讲解比较详细,但关于 Android 平台的 UVC XU 扩展协议的文章几乎没有什么实质内容。由于之前没有接触过这方面的内容,我决定在这里记录一下实现过程,以便让 Android 开发的小伙伴少走一些弯路。

UVC 扩展单元控制请求

扩展单元控制请求设置或读取扩展单元内的视频控件.

bmRequestTypebRequestwValue(2)wIndexwLengthData
00100001SET_CUR选择子扩展单元ID参数长度参数块
bmRequestTypebRequestwValue(2)wIndexwLengthData
10100001GET_CUR
GET_MIN
GET_MAX
GET_RES
GET_LEN
GET_INFO
选择子扩展单元ID参数长度参数块
  • bRequest字段指示请求正在操作的属性。Set请求不支持MIN、MAX和RES属性。
  • wValue字段在高字节中指定控制选择器(CS),在低位字节中指定零。控件选择器指示此请求正在处理的扩展单元中的哪个供应商定义的控件。拉展单元的选择器从1开始(0用于默认)。
  • GET_LEN请求查询指定控件的参数块的长度。当发出GET_LEN请求时,wLength字段应始终设置为2个字节的值。返回的结果应为同一控件上所有其他请求的指定长度。
  • SET_CUR 请求是可选的。

所有扩展单元控件都由供应商定义。供应商必须提供相关主机软件来编程这些控制。主机驱动程序将不了解控制语义,而是充当供应商提供的主机软件和设备之间的控制传输

通过使用GET_LEN请求,主机驱动程序将能够查询存储在供应商定义的控件中的长度和原始数据。虽然它不能解释这些数据,但如果需要,它可以保存和恢复这些控制设置。

调试工具介绍

不管是pc还是android,统一使用这个工具调试;

参考资料:UVC 官方文档及下载 - USB中文网

PC平台如何接入

Windows DS API说明

Windows本身有DS API,可以通过API和UVC设备进行XU交互。

UVC设备是基于RT-Thread开发的,RT-Thread系统内嵌了命令行交互功能。

那么要实现PC和设备的命令交互就只需要通信上实现PC发命令给设备以及设备返回打印结果给PC这两个功能。

可以通过XU SET_CUR往设备发命令,XU GET_CUR从设备读取打印信息。

Windows上需要一个软件来实现命令交互的shell,可以在开源软件putty上加上XU GET/SET就OK了。

附一张实现的XU shell界面。

PC代码接入

代码接入,建议直接依赖下面库就可以了

调用方法如下
(1)调用InitUsbCamLib函数初始化库
(2)调用GetCurCamDevs获取所有摄像头
(3)调用OpenUsbCamDev打开摄像头并获取handler
(4)调用GetExUnitInfo获取扩展单元信息,目前只能获取到node id,guid需要手动填写
(5)调用GetCtrlCmdLen获取命令长度
(6)调用UvcXuCommand执行扩展命令
(7)调用CloseUsbCamDev关闭设备
(8)调用UnInitUsbCamLib去初始化库

具体可以参考example.cpp文件

guid可以用UvcView.exe查看

下载链接:

百度云盘链接: 链接: https://pan.baidu.com/s/1g6Tgd1j3_-CaCg-mSxIScQ?pwd=9kve 提取码: 9kve

Android平台如何接入

  接入误区

 当收到这个需求时,相信很多小伙伴首先想到的是通过安卓的 API UsbManager 去实现。其实这是一个错误的思路,这样只会让你的努力白费。

USB host overview感兴趣的自己去看:USB host overview  |  Connectivity  |  Android Developers

Android代码接入

 这里我基于这个开源库去实现,感兴趣的直接去看:https://github.com/saki4510t/UVCCamera

 先说重点,发送xu命令是基于这个方法去实现的

UVCCamera.cpp 文件中增加你的协议代码。由于涉及到 C 语言的编写,如果你不熟悉 C 语言,建议花几天时间学习一下。下面是具体的代码示例:

int UVCCamera::setCircleLightBrightness(int lightBrightness) {
	ENTER();
	int result = EXIT_FAILURE;
	if (mDeviceHandle) {
		const uvc_extension_unit *xus = uvc_get_extension_units(mDeviceHandle);
	    //这里面写你自己的协议代码
	}
	RETURN(result, int);
}

在serenegiant_usb_UVCCamera.cpp里面引用,使外部java方法可以调用


static jint nativeSetCircleLightBrightness(JNIEnv *env, jobject thiz,
							 ID_TYPE id_camera, jint circleLightBrightness) {

	jint result = JNI_ERR;
	ENTER();
	UVCCamera *camera = reinterpret_cast<UVCCamera *>(id_camera);
	if (LIKELY(camera)) {
		result = camera->setCircleLightBrightness(circleLightBrightness);
	}
	RETURN(result, jint);
}
	{ "nativeSetCircleLightBrightness",	"(JI)I", (void *) nativeSetCircleLightBrightness },

java方法里面

	private static final native int nativeSetCircleLightBrightness(final long id_camera, final int lightBrightness);

总结

基本上,关于在 PC 和 Android 平台上如何使用 UVC XU 扩展协议发送命令的方法已经讲清楚了。如果还有不明白的小伙伴,欢迎留言交流。如果有更好的实现方法,也请分享在留言区。

  • 21
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值