前言

代码分析
H:\webrtc-20210315\webrtc-20210315\webrtc\webrtc-checkout\src\modules\video_capture\windows\sink_filter_ds.cc
CaptureInputPin::Receive
采集的数据首先经过这里。
STDMETHODIMP CaptureInputPin::Receive(IMediaSample* media_sample) {//RTC_DCHECK_RUN_ON(&capture_checker_);CaptureSinkFilter* const filter = static_cast<CaptureSinkFilter*>(Filter());if (flushing_.load(std::memory_order_relaxed))return S_FALSE;if (runtime_error_.load(std::memory_order_relaxed))return VFW_E_RUNTIME_ERROR;if (!capture_thread_id_) {// Make sure we set the thread name only once.capture_thread_id_ = GetCurrentThreadId();rtc::SetCurrentThreadName("webrtc_video_capture");}AM_SAMPLE2_PROPERTIES sample_props = {};GetSampleProperties(media_sample, &sample_props);// Has the format changed in this sample?if (sample_props.dwSampleFlags & AM_SAMPLE_TYPECHANGED) {// Check the derived class accepts the new format.// This shouldn't fail as the source must call QueryAccept first.// Note: This will modify resulting_capability_.// That should be OK as long as resulting_capability_ is only modified// on this thread while it is running (filter is not stopped), and only// modified on the main thread when the filter is stopped (i.e. this thread// is not running).if (!TranslateMediaTypeToVideoCaptureCapability(sample_props.pMediaType,&resulting_capability_)) {// Raise a runtime error if we fail the media typeruntime_error_ = true;EndOfStream();Filter()->NotifyEvent(EC_ERRORABORT, VFW_E_TYPE_NOT_ACCEPTED, 0);return VFW_E_INVALIDMEDIATYPE;}}filter->ProcessCapturedFrame(sample_props.pbBuffer, sample_props.lActual,resulting_capability_);return S_OK;}
—》 filter->ProcessCapturedFrame(sampleprops.pbBuffer, sample_props.lActual,
resulting_capability);
CaptureSinkFilter::ProcessCapturedFrame
void CaptureSinkFilter::ProcessCapturedFrame(unsigned char* buffer,size_t length,const VideoCaptureCapability& frame_info) {// Called on the capture thread.capture_observer_->IncomingFrame(buffer, length, frame_info);}
—》
int32_t VideoCaptureImpl::IncomingFrame(uint8_t* videoFrame,size_t videoFrameLength,const VideoCaptureCapability& frameInfo,int64_t captureTime /*=0*/) {MutexLock lock(&api_lock_);const int32_t width = frameInfo.width;const int32_t height = frameInfo.height;TRACE_EVENT1("webrtc", "VC::IncomingFrame", "capture_time", captureTime);// Not encoded, convert to I420.if (frameInfo.videoType != VideoType::kMJPEG &&CalcBufferSize(frameInfo.videoType, width, abs(height)) !=videoFrameLength) {RTC_LOG(LS_ERROR) << "Wrong incoming frame length.";return -1;}int stride_y = width;int stride_uv = (width + 1) / 2;int target_width = width;int target_height = abs(height);// SetApplyRotation doesn't take any lock. Make a local copy here.bool apply_rotation = apply_rotation_;if (apply_rotation) {// Rotating resolution when for 90/270 degree rotations.if (_rotateFrame == kVideoRotation_90 ||_rotateFrame == kVideoRotation_270) {target_width = abs(height);target_height = width;}}// Setting absolute height (in case it was negative).// In Windows, the image starts bottom left, instead of top left.// Setting a negative source height, inverts the image (within LibYuv).// TODO(nisse): Use a pool?rtc::scoped_refptr<I420Buffer> buffer = I420Buffer::Create(target_width, target_height, stride_y, stride_uv, stride_uv);libyuv::RotationMode rotation_mode = libyuv::kRotate0;if (apply_rotation) {switch (_rotateFrame) {case kVideoRotation_0:rotation_mode = libyuv::kRotate0;break;case kVideoRotation_90:rotation_mode = libyuv::kRotate90;break;case kVideoRotation_180:rotation_mode = libyuv::kRotate180;break;case kVideoRotation_270:rotation_mode = libyuv::kRotate270;break;}}// 将输入数据转为I420const int conversionResult = libyuv::ConvertToI420(videoFrame, videoFrameLength, buffer.get()->MutableDataY(),buffer.get()->StrideY(), buffer.get()->MutableDataU(),buffer.get()->StrideU(), buffer.get()->MutableDataV(),buffer.get()->StrideV(), 0, 0, // No Croppingwidth, height, target_width, target_height, rotation_mode,ConvertVideoType(frameInfo.videoType));if (conversionResult < 0) {RTC_LOG(LS_ERROR) << "Failed to convert capture frame from type "<< static_cast<int>(frameInfo.videoType) << "to I420.";return -1;}VideoFrame captureFrame =VideoFrame::Builder().set_video_frame_buffer(buffer).set_timestamp_rtp(0).set_timestamp_ms(rtc::TimeMillis()).set_rotation(!apply_rotation ? _rotateFrame : kVideoRotation_0).build();captureFrame.set_ntp_time_ms(captureTime);DeliverCapturedFrame(captureFrame);return 0;}
—> DeliverCapturedFrame(captureFrame);
VideoCaptureImpl::DeliverCapturedFrame
int32_t VideoCaptureImpl::DeliverCapturedFrame(VideoFrame& captureFrame) {UpdateFrameCount(); // frame count used for local frame rate callback.if (_dataCallBack) {_dataCallBack->OnFrame(captureFrame);}return 0;}
—> _dataCallBack->OnFrame(captureFrame);
h:\webrtc-20210315\webrtc-20210315\webrtc\webrtc-checkout\src\test\vcm_capturer.cc
VcmCapturer::OnFrame
void VcmCapturer::OnFrame(const VideoFrame& frame) {TestVideoCapturer::OnFrame(frame); // 里面调用broadcaster_.OnFrame分发数据}
