前言


源码分析
Conductor::AddTracks
void Conductor::AddTracks() {**// 创建视频设备rtc::scoped_refptr<CapturerTrackSource> video_device =CapturerTrackSource::Create();****}
—》 CapturerTrackSource::Create();
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));}}}
—》 webrtc::VideoCaptureFactory::CreateDeviceInfo());
VideoCaptureFactory::CreateDeviceInfo
VideoCaptureModule::DeviceInfo* VideoCaptureFactory::CreateDeviceInfo() {#if defined(WEBRTC_ANDROID) || defined(WEBRTC_MAC)return nullptr;#elsereturn videocapturemodule::VideoCaptureImpl::CreateDeviceInfo();#endif}
—》videocapturemodule::VideoCaptureImpl::CreateDeviceInfo();
VideoCaptureModule::DeviceInfo* VideoCaptureImpl::CreateDeviceInfo() {// TODO(tommi): Use the Media Foundation version on Vista and up.return DeviceInfoDS::Create();}
DeviceInfoDS::Create
// staticDeviceInfoDS* DeviceInfoDS::Create() {DeviceInfoDS* dsInfo = new DeviceInfoDS();if (!dsInfo || dsInfo->Init() != 0) {delete dsInfo;dsInfo = NULL;}return dsInfo;}
DeviceInfoDS::DeviceInfoDS()
DeviceInfoDS::DeviceInfoDS(): _dsDevEnum(NULL),_dsMonikerDevEnum(NULL),_CoUninitializeIsRequired(true) {// 1) Initialize the COM library (make Windows load the DLLs).//// CoInitializeEx must be called at least once, and is usually called only// once, for each thread that uses the COM library. Multiple calls to// CoInitializeEx by the same thread are allowed as long as they pass the same// concurrency flag, but subsequent valid calls return S_FALSE. To close the// COM library gracefully on a thread, each successful call to CoInitializeEx,// including any call that returns S_FALSE, must be balanced by a// corresponding call to CoUninitialize.///*Apartment-threading, while allowing for multiple threads of execution,serializes all incoming calls by requiring that calls to methods of objectscreated by this thread always run on the same thread the apartment/threadthat created them. In addition, calls can arrive only at message-queueboundaries (i.e., only during a PeekMessage, SendMessage, DispatchMessage,etc.). Because of this serialization, it is not typically necessary to writeconcurrency control into the code for the object, other than to avoid callsto PeekMessage and SendMessage during processing that must not be interruptedby other method invocations or calls to other objects in the sameapartment/thread.*//// CoInitializeEx(NULL, COINIT_APARTMENTTHREADED ); //|/// COINIT_SPEED_OVER_MEMORYHRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED); // Use COINIT_MULTITHREADED since Voice// Engine uses COINIT_MULTITHREADEDif (FAILED(hr)) {// Avoid calling CoUninitialize() since CoInitializeEx() failed._CoUninitializeIsRequired = FALSE;if (hr == RPC_E_CHANGED_MODE) {// Calling thread has already initialized COM to be used in a// single-threaded apartment (STA). We are then prevented from using STA.// Details: hr = 0x80010106 <=> "Cannot change thread mode after it is// set".//RTC_DLOG(LS_INFO) << __FUNCTION__<< ": CoInitializeEx(NULL, COINIT_APARTMENTTHREADED)"" => RPC_E_CHANGED_MODE, error 0x"<< rtc::ToHex(hr);}}}
DeviceInfoDS::Init()
int32_t DeviceInfoDS::Init() {// 创建SystemDeviceEnum的com组件HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC,IID_ICreateDevEnum, (void**)&_dsDevEnum);if (hr != NOERROR) {RTC_LOG(LS_INFO) << "Failed to create CLSID_SystemDeviceEnum, error 0x"<< rtc::ToHex(hr);return -1;}return 0;}
