我有一个使用 Microsoft Media Foundation 访问的视频流设备。它具有使用批量的附加功能。我想使用 libusb 连接到它。我的问题是我需要精确连接到与
IMFMediaSource
相同的设备。连接两个相同的设备我找不到将它们分开的方法。 VID和PID是相同的。我从 MF 得到的唯一东西是一个符号链接:\\?\usb#vid_----&pid_----&mi_00#8&20ba1d94&0&0000#{e5323777-f976-4f5b-9b55-b94699c46e44}\global
(删除了 vid 和 pid)。通过使用设备描述符的 libusb,我可以读取串行:$Rev:0001_CID:0009011D01502130_SN:76543210$
。在连接的设备上它们是不同的,但问题是我找不到方法来检查或连接这两个字符串以查看它是否是同一设备。
我获得符号链接的代码:
IMFAttributes* pAttributes = NULL;
IMFActivate** ppDevices = NULL;
HRESULT hr = EnumerateVideoDevices(pAttributes, ppDevices, availDeviceCount);
availDevice = new Device[availDeviceCount]; // initialise empty return array
// populate return array w/ devices
for (int i = 0; i < availDeviceCount; i++)
{
wchar_t* deviceFriendlyName;
UINT len = 0;
hr = ppDevices[i]->GetAllocatedString(MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME, &deviceFriendlyName, &len);
Device newDevice{ i, ToNarrow(deviceFriendlyName), NULL, 0 }; // TODO: check that change from unicode to String doesn't screw anything up (see ToNarrow, misc.h)
// retain for device change notificatios
ppDevices[i]->GetAllocatedString(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK,
&newDevice.g_pwszSymbolicLink, &newDevice.g_cchSymbolicLink);
availDevice[i] = newDevice;
}
这就是我使用 libusb 获得串口的方法:
String serial = LibUsb.getStringDescriptor(handle, descriptor.iSerialNumber());
过了一段时间,我发现视频流设备是整个USB设备的子设备。这就是我如何获得与 libusb 相同的序列号:
CONFIGRET LocateParent(PCWSTR pszDeviceInterface, WCHAR* parentDeviceID)
{
WCHAR buf[1024];
DEVPROPTYPE PropertyType;
ULONG BufferSize = sizeof(buf);
CONFIGRET err;
if (!(err = CM_Get_Device_Interface_Property(pszDeviceInterface, &DEVPKEY_Device_InstanceId, &PropertyType, (PBYTE)buf, &BufferSize, 0))) {
if (PropertyType == DEVPROP_TYPE_STRING) {
DEVINST dnDevInst;
if (!(err = CM_Locate_DevNode(&dnDevInst, buf, CM_LOCATE_DEVNODE_NORMAL))) {
// Get Parent Device ID
DEVINST devInstParent;
err = CM_Get_Parent(&devInstParent, dnDevInst, 0);
if (err == CR_SUCCESS) {
return CM_Get_Device_ID(devInstParent, parentDeviceID, 1024, 0);
}
}
}
else {
err = CR_WRONG_TYPE;
}
}
return err;
}