WebRTC视频 05 - 视频采集类 VideoCaptureDS 下篇

WebRTC视频 01 - 视频采集整体架构
WebRTC视频 02 - 视频采集类 VideoCaptureModule
WebRTC视频 03 - 视频采集类 VideoCaptureDS 上篇
WebRTC视频 04 - 视频采集类 VideoCaptureDS 中篇
WebRTC视频 05 - 视频采集类 VideoCaptureDS 下篇(本文)

一、前言:

前面介绍了视频数据采集,那么采集到的数据如何上传给上层应用的?本节看看。

二、流程图:

在这里插入图片描述

  1. CaptureFilterCamera采集到数据之后交给SinkFilter
  2. 通过SinkFilter获取到数据之后,会调用VideoCaptureImplIncomingFrame
  3. 接着调用DeliverCapturedFrame,里面会调用RegisterCaptureDataCallbackonFrame,将数据传给onFrame函数;
  4. 接下来再交给VcmCapturer::OnFrame,里面会交给VideoBroadcaster
  5. VideoBroadcaster::OnFrame会将采集到数据进行分两路,本地渲染和编码器(注意看数据有没有copy);
  6. 还记得本地渲染器和编码器什么时候加入到VideoBroadcaster当中的吗?本地渲染器是StartLocalRenderer时候加入的,编码器是媒体协商最后一步SetRemoteDescription的时候加入的;

三、代码走读:

首先看看SinkFilter接收数据的地方:

/**
 * 接收采集到的视频数据时候,首先会进入到这儿
 * @param media_sample:就是采集到的数据
 */
STDMETHODIMP CaptureInputPin::Receive(IMediaSample* media_sample) {
   
   
  RTC_DCHECK_RUN_ON(&capture_checker_);
  // 通过Filter()获取到这个pin所属的filter,也就是sinkFilter
  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;
  // 确保采集线程id已经获得,并给线程起个名字webrtc_video_capture
  if (!capture_thread_id_) {
   
   
    // Make sure we set the thread name only once.
    capture_thread_id_ = GetCurrentThreadId();
    rtc::SetCurrentThreadName("webrtc_video_capture");
  }
  // 获取采样属性,看其中是否包含AM_SAMPLE_TYPECHANGED,如果包含了,会做一些处理
  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 type
      runtime_error_ = true;
      EndOfStream();
      Filter()->NotifyEvent(EC_ERRORABORT, VFW_E_TYPE_NOT_ACCEPTED, 0);
      return VFW_E_INVALIDMEDIATYPE;
    }
  }
  // 收到数据之后调用这个方法将数据从pin传给filter
  filter->ProcessCapturedFrame(sample_props.pbBuffer, sample_props.lActual,
                               resulting_capability_
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值