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 devices
RELEASE_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 drivers
if ((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;
}