本地的VideoFrame渲染一(VideoTrack)

VideoTrack是webrtc中视频流最上层的接口,它内部其实是经过层层封装,对于本地的VideoTrack(远端的还没研究),它最终通过VideoCaptureImpl完成本地视频的采集,VideoCaptureImpl实际上是通过DirectShow(windows平台上)与硬件打交道的。可以先看下它简化后的关系:
这里写图片描述

那么视频帧是如何通过ViedoTrack渲染出来的呢,先看另一个接口:
这里写图片描述

再看回开始那个VideoTrack的类图,其实它们共同实现了VideoSourceInterface接口:
这里写图片描述

从这可以看出点端倪来,VideoRender类继承VideoSinkInterface接口,当一帧视频准备好的时候,OnFrame(const VideoFrameT&)将被调用,前提是要先把VideoRender通过VideoTrack的AddOrUpdateSink()传递进去。可以看下传递过程,画完这个之后,我终于明白为什么他的名字叫Sink(下沉)了……
这里写图片描述

从上面可以看出,从上层的VideoTrack的AddOrUpdateSink()通过层层传递最终调用WebRtcVideoCapturer(VideoCapturer)的AddOrUpdateSink(),而它又调用了broadcaster_.AddOrUpdateSink(sink, wants);我们先来看看broadcaster_的类:

这里写图片描述

实际上,当调用VideoBroadcaster的AddOrUpdateSink(sink, wants)会调VideoSourceBase的AddOrUpdateSink(sink, wants); VideoSourceBase的代码如下:

void VideoSourceBase::AddOrUpdateSink(
    VideoSinkInterface<cricket::VideoFrame>* sink,
    const VideoSinkWants& wants) {
  RTC_DCHECK(thread_checker_.CalledOnValidThread());
  RTC_DCHECK(sink != nullptr);

  SinkPair* sink_pair = FindSinkPair(sink);
  if (!sink_pair) {
    sinks_.push_back(SinkPair(sink, wants));
  } else {
    sink_pair->wants = wants;
  }
}

可见AddOrUpdateSink里将VideoSinkInterface添加到sinks_中,sinks_是一个SinkPair的数组,如下:

  struct SinkPair {
    SinkPair(VideoSinkInterface<cricket::VideoFrame>* sink,
             VideoSinkWants wants)
        : sink(sink), wants(wants) {}
    VideoSinkInterface<cricket::VideoFrame>* sink;
    VideoSinkWants wants;
  };

它内部就包含了VideoSinkInterface和VideoSinkWants(现在先不管VideoSinkWants)。

写了这么多,还是没有回答如何渲染一帧视频出来,这又要联系到VideoCapturer类的实现,下一篇文章再说明。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值