8-8 源码分析-获取视频设备信息 - 图1

CapturerTrackSource::Create()

  1. static rtc::scoped_refptr<CapturerTrackSource> Create() {
  2. const size_t kWidth = 640;
  3. const size_t kHeight = 480;
  4. const size_t kFps = 30;
  5. std::unique_ptr<webrtc::test::VcmCapturer> capturer;
  6. std::unique_ptr<webrtc::VideoCaptureModule::DeviceInfo> info(
  7. webrtc::VideoCaptureFactory::CreateDeviceInfo());
  8. if (!info) {
  9. return nullptr;
  10. }
  11. int num_devices = info->NumberOfDevices();
  12. for (int i = 0; i < num_devices; ++i) {
  13. capturer = absl::WrapUnique(
  14. webrtc::test::VcmCapturer::Create(kWidth, kHeight, kFps, i));
  15. if (capturer) {
  16. return new rtc::RefCountedObject<CapturerTrackSource>(
  17. std::move(capturer));
  18. }
  19. }
  20. return nullptr;
  21. }

—》 int num_devices = info->NumberOfDevices();

  1. uint32_t DeviceInfoDS::NumberOfDevices() {
  2. MutexLock lock(&_apiLock);
  3. return GetDeviceInfo(0, 0, 0, 0, 0, 0, 0);
  4. }

—》GetDeviceInfo(0, 0, 0, 0, 0, 0, 0);

  1. int32_t DeviceInfoDS::GetDeviceInfo(uint32_t deviceNumber, 第几个设备
  2. char* deviceNameUTF8, 设备名称
  3. uint32_t deviceNameLength, 设备名称长度
  4. char* deviceUniqueIdUTF8, 唯一标识
  5. uint32_t deviceUniqueIdUTF8Length,
  6. char* productUniqueIdUTF8, 生产的标识
  7. uint32_t productUniqueIdUTF8Length)
  8. {
  9. // enumerate all video capture devices
  10. RELEASE_AND_CLEAR(_dsMonikerDevEnum);
  11. // 指定获取视频设备
  12. HRESULT hr = _dsDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,
  13. &_dsMonikerDevEnum, 0);
  14. if (hr != NOERROR) {
  15. RTC_LOG(LS_INFO) << "Failed to enumerate CLSID_SystemDeviceEnum, error 0x"
  16. << rtc::ToHex(hr) << ". No webcam exist?";
  17. return 0;
  18. }
  19. _dsMonikerDevEnum->Reset();
  20. ULONG cFetched;
  21. IMoniker* pM;
  22. int index = 0;
  23. // 枚举设备,默认只有一个设备,只会循环一次
  24. while (S_OK == _dsMonikerDevEnum->Next(1, &pM, &cFetched)) {
  25. IPropertyBag* pBag;
  26. hr = pM->BindToStorage(0, 0, IID_IPropertyBag, (void**)&pBag);
  27. if (S_OK == hr) {
  28. // Find the description or friendly name.
  29. VARIANT varName;
  30. VariantInit(&varName);
  31. hr = pBag->Read(L"Description", &varName, 0);
  32. if (FAILED(hr)) {
  33. hr = pBag->Read(L"FriendlyName", &varName, 0);
  34. }
  35. if (SUCCEEDED(hr)) {
  36. // ignore all VFW drivers
  37. if ((wcsstr(varName.bstrVal, (L"(VFW)")) == NULL) &&
  38. (_wcsnicmp(varName.bstrVal, (L"Google Camera Adapter"), 21) != 0)) {
  39. // Found a valid device.
  40. if (index == static_cast<int>(deviceNumber)) {
  41. int convResult = 0;
  42. if (deviceNameLength > 0) {
  43. convResult = WideCharToMultiByte(CP_UTF8, 0, varName.bstrVal, -1,
  44. (char*)deviceNameUTF8,
  45. deviceNameLength, NULL, NULL);
  46. if (convResult == 0) {
  47. RTC_LOG(LS_INFO) << "Failed to convert device name to UTF8, "
  48. "error = "
  49. << GetLastError();
  50. return -1;
  51. }
  52. }
  53. if (deviceUniqueIdUTF8Length > 0) {
  54. hr = pBag->Read(L"DevicePath", &varName, 0);
  55. if (FAILED(hr)) {
  56. strncpy_s((char*)deviceUniqueIdUTF8, deviceUniqueIdUTF8Length,
  57. (char*)deviceNameUTF8, convResult);
  58. RTC_LOG(LS_INFO) << "Failed to get "
  59. "deviceUniqueIdUTF8 using "
  60. "deviceNameUTF8";
  61. } else {
  62. convResult = WideCharToMultiByte(
  63. CP_UTF8, 0, varName.bstrVal, -1, (char*)deviceUniqueIdUTF8,
  64. deviceUniqueIdUTF8Length, NULL, NULL);
  65. if (convResult == 0) {
  66. RTC_LOG(LS_INFO) << "Failed to convert device "
  67. "name to UTF8, error = "
  68. << GetLastError();
  69. return -1;
  70. }
  71. if (productUniqueIdUTF8 && productUniqueIdUTF8Length > 0) {
  72. GetProductId(deviceUniqueIdUTF8, productUniqueIdUTF8,
  73. productUniqueIdUTF8Length);
  74. }
  75. }
  76. }
  77. }
  78. ++index; // increase the number of valid devices
  79. }
  80. }
  81. VariantClear(&varName);
  82. pBag->Release();
  83. pM->Release();
  84. }
  85. }
  86. if (deviceNameLength) {
  87. RTC_DLOG(LS_INFO) << __FUNCTION__ << " " << deviceNameUTF8;
  88. }
  89. return index;
  90. }