有的时候我们需要通过HUB接多个完全一样的UVC设备,即每个设备的VID和PID等信息是完全一样的,libuvc和libusb原生就支持同vidpid设备, 且libuvc提供了查找多个设备的接口uvc_find_devices, 我们就来实现一个小的Demo进行测试。
代码见:https://github.com/qinyunti/uvc_demo.git
代码详见test_samevidpid.c
test_samevidpid_main中
先初始化上下文
res = uvc_init(&ctx, NULL);
if (res < 0) {
uvc_perror(res, "uvc_init");
return res;
}
printf("UVC initialized\r\n");
和最后的退出释放对应
uvc_exit(ctx);
printf("UVC exited");
然后是查找设备,这里使用uvc_find_devices查找指定VID和PID的多个设备SN为空不指定。
这里传入&devs是uvc_device_t ***类型
devs是uvc_device_t **类型,所以函数调用后返回之devs指向的是多个
uvc_device_t *的设备列表。即每一个devs[i]都是一个uvc_device_t *的设备。
res = uvc_find_devices(
ctx, &devs,
0x1993, 0x0101, NULL);
if(devs == NULL){
uvc_exit(ctx);
printf("no device founded");
}
计算有多少个设备
for(int i=0; ; i++){
if(devs[i] != NULL){
dev_num++;
}else{
break;
}
}
和解引用设备对应
for(int i=0; i
{
uvc_unref_device(devs[i]);
}
然后是循环打开多个uvc设备和启动流
if (res < 0)
{
uvc_perror(res, "uvc_find_devices");
}
else
{
printf("Device found\r\n");
for(int i=0; i
{
res = uvc_open(devs[i], &devh[i]);
if (res < 0)
{
uvc_perror(res, "uvc_open");
}
else
{
printf("Device opened %d\r\n",dev_num);
uvc_print_diag(devh[i], stderr);
res = uvc_get_stream_ctrl_format_size(
devh[i], &ctrl[i], UVC_FRAME_FORMAT_MJPEG, 1280, 720, 0
);
uvc_print_stream_ctrl(&ctrl[i], stderr);
if (res < 0)
{
uvc_perror(res, "get_mode");
}
else
{
res = uvc_start_streaming(devh[i], &ctrl[i], cb, (void*)i, 0);
if (res < 0)
{
uvc_perror(res, "start_streaming");
}
else
{
printf("Streaming for 10 seconds...");
}
}
}
}
执行10S
Sleep(10000);
和停止流对应
for(int i=0; i
{
uvc_stop_streaming(devh[i]);
printf("Done streaming %d.\r\n",i);
}
和关闭uvc设备对应
for(int i=0; i
{
uvc_unref_device(devs[i]);
}
回调函数中
static void cb(uvc_frame_t *frame, void *ptr) {
uvc_frame_t *bgr;
uvc_error_t ret;
printf("callback! length = %zu, ptr = %p\n", frame->data_bytes, ptr);
bgr = uvc_allocate_frame(frame->width * frame->height * 3);
if (!bgr) {
printf("unable to allocate bgr frame!");
return;
}
/* 格式解析 */
ret = uvc_any2bgr(frame, bgr);
if (ret) {
uvc_perror(ret, "uvc_any2bgr");
uvc_free_frame(bgr);
return;
}
// 显示等操作
uvc_free_frame(bgr);
}
我们通过ptr参数区分是哪一个设备,打印如下
printf("callback! length = %zu, ptr = %p\n", frame->data_bytes, ptr);
使用HUB接入两个一样的UVC设备,
注意参照readme修改PID和VID,重新编译
使用build/Desktop_Qt_6_6_1_MinGW_64_bit-Debug/debug/uvc.exe测试
可以看到回调打印如下,两个设备都工作OK。
Libusb和libuvc都原生支持同cidpid的多设备,使用uvc_find_devices可以打开多个设备,不过注意传入参数是三级指针,使用时需要注意。