DepthCameraPtr TintinCDKCameraFactory::getDepthCamera(DevicePtr device) { if(device->interfaceID() == Device::USB) { USBDevice &d = (USBDevice &)*device; if(d.vendorID() == TINTIN_CDK_VENDOR_ID && (d.productID() == TINTIN_CDK_PRODUCT_BULK || d.productID() == TINTIN_CDK_PRODUCT_UVC)) { return DepthCameraPtr(new TintinCDKCamera(device)); } } return 0; }
UVCPrivate::UVCPrivate(DevicePtr usb) { if (usb->interfaceID() != Device::USB) return; USBSystem sys; String devicePath = sys.getDeviceNode((USBDevice &)*usb); if (!devicePath.size()) { logger(LOG_ERROR) << "UVC: Could not get device path for device '" << usb->id() << "'" << std::endl; return; } DWORD devInst; if (!sys.getUSBSystemPrivate().getDevInst(devicePath, devInst)) { logger(LOG_ERROR) << "UVC: Could not get devInst for device '" << usb->id() << "'" << std::endl; return; } HRESULT hr = S_OK; IMoniker *moniker; Ptr<ICreateDevEnum> devEnum; Ptr<IEnumMoniker> classEnum; void *p; CoInitializeEx(NULL, COINIT_MULTITHREADED); // Create the system device enumerator if ((hr = (CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC, IID_ICreateDevEnum, (void **)&p))) != S_OK) { logger(LOG_ERROR) << "UVC: Failed to get ICreateDevEnum enumerator" << std::endl; return; } devEnum = Ptr<ICreateDevEnum>((ICreateDevEnum *)p, [](ICreateDevEnum *i) { i->Release(); }); // Create an enumerator for the video capture devices if ((hr = devEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, (IEnumMoniker **)&p, 0)) != S_OK) { logger(LOG_ERROR) << "UVC: Failed to get VideoInputDeviceCategory class enumerator" << std::endl; return; } // If there are no enumerators for the requested type, then // CreateClassEnumerator will succeed, but pClassEnum will be NULL. if (p == NULL) { logger(LOG_ERROR) << "UVC: Failed to get any video input devices in the enumerator" << std::endl; return; } classEnum = Ptr<IEnumMoniker>((IEnumMoniker *)p, [](IEnumMoniker *i) { i->Release(); }); while ((hr = classEnum->Next(1, &moniker, NULL)) == S_OK) { IPropertyBag *propBag; if ((hr = moniker->BindToStorage(0, 0, IID_IPropertyBag, (void**)&propBag)) != S_OK) { logger(LOG_WARNING) << "UVC: Could not get properties for current moniker" << std::endl; continue; } VARIANT varName; VariantInit(&varName); if ((hr = propBag->Read(L"DevicePath", &varName, 0)) != S_OK) { logger(LOG_WARNING) << "UVC: Could not get DevicePath for current moniker" << std::endl; continue; } _bstr_t b(varName.bstrVal); String devPath = b; VariantClear(&varName); DWORD dInst; DWORD parentDevInst; if (!sys.getUSBSystemPrivate().getDevInst(devPath, dInst, (LPGUID)&AM_KSCATEGORY_CAPTURE)) //AM_KSCATEGORY_VIDEO { logger(LOG_WARNING) << "UVC: Could not get DevInst for DevicePath = " << devPath << std::endl; continue; } if (CM_Get_Parent(&parentDevInst, dInst, 0) != CR_SUCCESS) { logger(LOG_WARNING) << "UVC: Could not get parent DevInst for DevicePath = " << devPath << std::endl; continue; } if (parentDevInst == devInst) // Check whether our USBDevice's DevInst matches with IMoniker's parent's DevInst matches { if (usb->channelID() >= 0) { auto x = devPath.find("&mi_"); if (x != String::npos) { char *endptr; int channel = strtol(devPath.c_str() + x + 4, &endptr, 10); if (channel != usb->channelID()) continue; } else { logger(LOG_ERROR) << "UVC: Could not find channel ID of current device '" << devPath << "'" << std::endl; continue; } } if ((hr = moniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&p)) != S_OK) { logger(LOG_ERROR) << "UVC: Could not get the IBaseFilter for the current video input device" << std::endl; continue; } _captureFilter = Ptr<IBaseFilter>((IBaseFilter *)p, [](IBaseFilter *d) { d->Release(); }); _captureFilter->AddRef(); break; } } }