CapturerTrackSource::Create()
static rtc::scoped_refptr<CapturerTrackSource> Create() {const size_t kWidth = 640;const size_t kHeight = 480;const size_t kFps = 30;std::unique_ptr<webrtc::test::VcmCapturer> capturer;std::unique_ptr<webrtc::VideoCaptureModule::DeviceInfo> info(webrtc::VideoCaptureFactory::CreateDeviceInfo());if (!info) {return nullptr;}int num_devices = info->NumberOfDevices();for (int i = 0; i < num_devices; ++i) {capturer = absl::WrapUnique(webrtc::test::VcmCapturer::Create(kWidth, kHeight, kFps, i));if (capturer) {return new rtc::RefCountedObject<CapturerTrackSource>(std::move(capturer));}}return nullptr;}
—》 int num_devices = info->NumberOfDevices();
uint32_t DeviceInfoDS::NumberOfDevices() {MutexLock lock(&_apiLock);return GetDeviceInfo(0, 0, 0, 0, 0, 0, 0);}
—》GetDeviceInfo(0, 0, 0, 0, 0, 0, 0);
int32_t DeviceInfoDS::GetDeviceInfo(uint32_t deviceNumber, 第几个设备char* deviceNameUTF8, 设备名称uint32_t deviceNameLength, 设备名称长度char* deviceUniqueIdUTF8, 唯一标识uint32_t deviceUniqueIdUTF8Length,char* productUniqueIdUTF8, 生产的标识uint32_t productUniqueIdUTF8Length){// enumerate all video capture devicesRELEASE_AND_CLEAR(_dsMonikerDevEnum);// 指定获取视频设备HRESULT hr = _dsDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,&_dsMonikerDevEnum, 0);if (hr != NOERROR) {RTC_LOG(LS_INFO) << "Failed to enumerate CLSID_SystemDeviceEnum, error 0x"<< rtc::ToHex(hr) << ". No webcam exist?";return 0;}_dsMonikerDevEnum->Reset();ULONG cFetched;IMoniker* pM;int index = 0;// 枚举设备,默认只有一个设备,只会循环一次while (S_OK == _dsMonikerDevEnum->Next(1, &pM, &cFetched)) {IPropertyBag* pBag;hr = pM->BindToStorage(0, 0, IID_IPropertyBag, (void**)&pBag);if (S_OK == hr) {// Find the description or friendly name.VARIANT varName;VariantInit(&varName);hr = pBag->Read(L"Description", &varName, 0);if (FAILED(hr)) {hr = pBag->Read(L"FriendlyName", &varName, 0);}if (SUCCEEDED(hr)) {// ignore all VFW driversif ((wcsstr(varName.bstrVal, (L"(VFW)")) == NULL) &&(_wcsnicmp(varName.bstrVal, (L"Google Camera Adapter"), 21) != 0)) {// Found a valid device.if (index == static_cast<int>(deviceNumber)) {int convResult = 0;if (deviceNameLength > 0) {convResult = WideCharToMultiByte(CP_UTF8, 0, varName.bstrVal, -1,(char*)deviceNameUTF8,deviceNameLength, NULL, NULL);if (convResult == 0) {RTC_LOG(LS_INFO) << "Failed to convert device name to UTF8, ""error = "<< GetLastError();return -1;}}if (deviceUniqueIdUTF8Length > 0) {hr = pBag->Read(L"DevicePath", &varName, 0);if (FAILED(hr)) {strncpy_s((char*)deviceUniqueIdUTF8, deviceUniqueIdUTF8Length,(char*)deviceNameUTF8, convResult);RTC_LOG(LS_INFO) << "Failed to get ""deviceUniqueIdUTF8 using ""deviceNameUTF8";} else {convResult = WideCharToMultiByte(CP_UTF8, 0, varName.bstrVal, -1, (char*)deviceUniqueIdUTF8,deviceUniqueIdUTF8Length, NULL, NULL);if (convResult == 0) {RTC_LOG(LS_INFO) << "Failed to convert device ""name to UTF8, error = "<< GetLastError();return -1;}if (productUniqueIdUTF8 && productUniqueIdUTF8Length > 0) {GetProductId(deviceUniqueIdUTF8, productUniqueIdUTF8,productUniqueIdUTF8Length);}}}}++index; // increase the number of valid devices}}VariantClear(&varName);pBag->Release();pM->Release();}}if (deviceNameLength) {RTC_DLOG(LS_INFO) << __FUNCTION__ << " " << deviceNameUTF8;}return index;}
