前言image.png

image.png

image.png

image.png

源码分析

image.png

Conductor::AddTracks

  1. void Conductor::AddTracks() {
  2. **
  3. // 创建视频设备
  4. rtc::scoped_refptr<CapturerTrackSource> video_device =
  5. CapturerTrackSource::Create();
  6. ****
  7. }

—》 CapturerTrackSource::Create();

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. }

—》 webrtc::VideoCaptureFactory::CreateDeviceInfo());

VideoCaptureFactory::CreateDeviceInfo

  1. VideoCaptureModule::DeviceInfo* VideoCaptureFactory::CreateDeviceInfo() {
  2. #if defined(WEBRTC_ANDROID) || defined(WEBRTC_MAC)
  3. return nullptr;
  4. #else
  5. return videocapturemodule::VideoCaptureImpl::CreateDeviceInfo();
  6. #endif
  7. }

—》videocapturemodule::VideoCaptureImpl::CreateDeviceInfo();

  1. VideoCaptureModule::DeviceInfo* VideoCaptureImpl::CreateDeviceInfo() {
  2. // TODO(tommi): Use the Media Foundation version on Vista and up.
  3. return DeviceInfoDS::Create();
  4. }

—》 DeviceInfoDS::Create();

DeviceInfoDS::Create

  1. // static
  2. DeviceInfoDS* DeviceInfoDS::Create() {
  3. DeviceInfoDS* dsInfo = new DeviceInfoDS();
  4. if (!dsInfo || dsInfo->Init() != 0) {
  5. delete dsInfo;
  6. dsInfo = NULL;
  7. }
  8. return dsInfo;
  9. }

—》

DeviceInfoDS::DeviceInfoDS()

  1. DeviceInfoDS::DeviceInfoDS()
  2. : _dsDevEnum(NULL),
  3. _dsMonikerDevEnum(NULL),
  4. _CoUninitializeIsRequired(true) {
  5. // 1) Initialize the COM library (make Windows load the DLLs).
  6. //
  7. // CoInitializeEx must be called at least once, and is usually called only
  8. // once, for each thread that uses the COM library. Multiple calls to
  9. // CoInitializeEx by the same thread are allowed as long as they pass the same
  10. // concurrency flag, but subsequent valid calls return S_FALSE. To close the
  11. // COM library gracefully on a thread, each successful call to CoInitializeEx,
  12. // including any call that returns S_FALSE, must be balanced by a
  13. // corresponding call to CoUninitialize.
  14. //
  15. /*Apartment-threading, while allowing for multiple threads of execution,
  16. serializes all incoming calls by requiring that calls to methods of objects
  17. created by this thread always run on the same thread the apartment/thread
  18. that created them. In addition, calls can arrive only at message-queue
  19. boundaries (i.e., only during a PeekMessage, SendMessage, DispatchMessage,
  20. etc.). Because of this serialization, it is not typically necessary to write
  21. concurrency control into the code for the object, other than to avoid calls
  22. to PeekMessage and SendMessage during processing that must not be interrupted
  23. by other method invocations or calls to other objects in the same
  24. apartment/thread.*/
  25. /// CoInitializeEx(NULL, COINIT_APARTMENTTHREADED ); //|
  26. /// COINIT_SPEED_OVER_MEMORY
  27. HRESULT hr = CoInitializeEx(
  28. NULL, COINIT_MULTITHREADED); // Use COINIT_MULTITHREADED since Voice
  29. // Engine uses COINIT_MULTITHREADED
  30. if (FAILED(hr)) {
  31. // Avoid calling CoUninitialize() since CoInitializeEx() failed.
  32. _CoUninitializeIsRequired = FALSE;
  33. if (hr == RPC_E_CHANGED_MODE) {
  34. // Calling thread has already initialized COM to be used in a
  35. // single-threaded apartment (STA). We are then prevented from using STA.
  36. // Details: hr = 0x80010106 <=> "Cannot change thread mode after it is
  37. // set".
  38. //
  39. RTC_DLOG(LS_INFO) << __FUNCTION__
  40. << ": CoInitializeEx(NULL, COINIT_APARTMENTTHREADED)"
  41. " => RPC_E_CHANGED_MODE, error 0x"
  42. << rtc::ToHex(hr);
  43. }
  44. }
  45. }

DeviceInfoDS::Init()

  1. int32_t DeviceInfoDS::Init() {
  2. // 创建SystemDeviceEnum的com组件
  3. HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC,
  4. IID_ICreateDevEnum, (void**)&_dsDevEnum);
  5. if (hr != NOERROR) {
  6. RTC_LOG(LS_INFO) << "Failed to create CLSID_SystemDeviceEnum, error 0x"
  7. << rtc::ToHex(hr);
  8. return -1;
  9. }
  10. return 0;
  11. }