前言

CLSCTX_INPROC_SERVER 导入的COM组件,跟当前逻辑共用同一个进程。


代码分析
CapturerTrackSource::Create
H:\webrtc-20210315\webrtc-20210315\webrtc\webrtc-checkout\src\examples\peerconnection\client\conductor.cc
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;}
—-》 capturer = absl::WrapUnique(
webrtc::test::VcmCapturer::Create(kWidth, kHeight, kFps, i));
VcmCapturer::Create
VcmCapturer* VcmCapturer::Create(size_t width,size_t height,size_t target_fps,size_t capture_device_index) {std::unique_ptr<VcmCapturer> vcm_capturer(new VcmCapturer());if (!vcm_capturer->Init(width, height, target_fps, capture_device_index)) {RTC_LOG(LS_WARNING) << "Failed to create VcmCapturer(w = " << width<< ", h = " << height << ", fps = " << target_fps<< ")";return nullptr;}return vcm_capturer.release();}
—》vcm_capturer->Init(width, height, target_fps, capture_device_index)
VcmCapturer::Init
bool VcmCapturer::Init(size_t width,size_t height,size_t target_fps,size_t capture_device_index) {std::unique_ptr<VideoCaptureModule::DeviceInfo> device_info(VideoCaptureFactory::CreateDeviceInfo());// 获取设备名称char device_name[256];char unique_name[256];if (device_info->GetDeviceName(static_cast<uint32_t>(capture_device_index),device_name, sizeof(device_name), unique_name,sizeof(unique_name)) != 0) {Destroy();return false;}//根据设备名称,创建VideoCaptureModule实例vcm_ = webrtc::VideoCaptureFactory::Create(unique_name);if (!vcm_) {return false;}// 创建成功,则传入采集数据回调,当采集到视频数据就会调用回调vcm_->RegisterCaptureDataCallback(this);// 获取设备的能力device_info->GetCapability(vcm_->CurrentDeviceName(), 0, capability_);// 根据传入参数传入到capability_变量中capability_.width = static_cast<int32_t>(width);capability_.height = static_cast<int32_t>(height);capability_.maxFPS = static_cast<int32_t>(target_fps);capability_.videoType = VideoType::kI420;// vcm实例以capability_的值开始采集,此时,设备已经开始工作了。if (vcm_->StartCapture(capability_) != 0) {Destroy();return false;}RTC_CHECK(vcm_->CaptureStarted());return true;}
—》 vcm_ = webrtc::VideoCaptureFactory::Create(unique_name);
VideoCaptureFactory::Create
rtc::scoped_refptr<VideoCaptureModule> VideoCaptureFactory::Create(const char* deviceUniqueIdUTF8) {#if defined(WEBRTC_ANDROID) || defined(WEBRTC_MAC)return nullptr;#elsereturn videocapturemodule::VideoCaptureImpl::Create(deviceUniqueIdUTF8);#endif
—》videocapturemodule::VideoCaptureImpl::Create(deviceUniqueIdUTF8);
VideoCaptureImpl::Create
rtc::scoped_refptr<VideoCaptureModule> VideoCaptureImpl::Create(const char* device_id) {if (device_id == nullptr)return nullptr;// TODO(tommi): Use Media Foundation implementation for Vista and up.rtc::scoped_refptr<VideoCaptureDS> capture(new rtc::RefCountedObject<VideoCaptureDS>());if (capture->Init(device_id) != 0) {return nullptr;}return capture;}
VideoCaptureDS::Init
int32_t VideoCaptureDS::Init(const char* deviceUniqueIdUTF8) {const int32_t nameLength = (int32_t)strlen((char*)deviceUniqueIdUTF8);if (nameLength > kVideoCaptureUniqueNameLength)return -1;// Store the device name_deviceUniqueId = new (std::nothrow) char[nameLength + 1];memcpy(_deviceUniqueId, deviceUniqueIdUTF8, nameLength + 1);if (_dsInfo.Init() != 0)return -1;_captureFilter = _dsInfo.GetDeviceFilter(deviceUniqueIdUTF8);if (!_captureFilter) {RTC_LOG(LS_INFO) << "Failed to create capture filter.";return -1;}// Get the interface for DirectShow's GraphBuilderHRESULT hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,IID_IGraphBuilder, (void**)&_graphBuilder);if (FAILED(hr)) {RTC_LOG(LS_INFO) << "Failed to create graph builder.";return -1;}// 获取IID_IMediaControl接口hr = _graphBuilder->QueryInterface(IID_IMediaControl, (void**)&_mediaControl);if (FAILED(hr)) {RTC_LOG(LS_INFO) << "Failed to create media control builder.";return -1;}hr = _graphBuilder->AddFilter(_captureFilter, CAPTURE_FILTER_NAME);if (FAILED(hr)) {RTC_LOG(LS_INFO) << "Failed to add the capture device to the graph.";return -1;}_outputCapturePin = GetOutputPin(_captureFilter, PIN_CATEGORY_CAPTURE);if (!_outputCapturePin) {RTC_LOG(LS_INFO) << "Failed to get output capture pin";return -1;}// Create the sink filte used for receiving Captured frames.sink_filter_ = new ComRefCount<CaptureSinkFilter>(this);hr = _graphBuilder->AddFilter(sink_filter_, SINK_FILTER_NAME);if (FAILED(hr)) {RTC_LOG(LS_INFO) << "Failed to add the send filter to the graph.";return -1;}_inputSendPin = GetInputPin(sink_filter_);if (!_inputSendPin) {RTC_LOG(LS_INFO) << "Failed to get input send pin";return -1;}// Temporary connect here.// This is done so that no one else can use the capture device.if (SetCameraOutput(_requestedCapability) != 0) {return -1;}// 在后面VcmCapturer::Init()中调用vcm_->StartCapture(capability_)的时候,才开始采集。// H:\webrtc-20210315\webrtc-20210315\webrtc\webrtc-checkout\src\test\vcm_capturer.cchr = _mediaControl->Pause();if (FAILED(hr)) {RTC_LOG(LS_INFO)<< "Failed to Pause the Capture device. Is it already occupied? " << hr;return -1;}RTC_LOG(LS_INFO) << "Capture device '" << deviceUniqueIdUTF8<< "' initialized.";return 0;}

