VideoBroadcaster属于vcm capture中的一个成员, 通过vcm capture 获取到采集的数据之后,再通过VideoBroadcaster分发出去.
这里主要讲解一下视频是如何被VideoBroadcaster分发给不同的对象的.
再以上函数中, for循环遍历sink_pairs,
注:
-
每一个sink代表一个输出对象;
-
每一个sink_pair是一个输出对象的key-value值;
-
所有需要接收视频数据的对象都会被组装成sink_pair插入到sink_pairs列表中;
if(是否需要一帧黑帧){
} else if (!上一帧发送给了sinks中的所有目标&&这一帧的宽高发生了变化) {
//由于上一帧没有发送到一些接收器,没有可靠的更新信息可用,所以我们需要清除更新rect。
} else {
sink_pair.sink->OnFrame(frame); //将数据分发个该对象
}
那么sink_pairs中的成员从何而来?
-
main_wnd_->StartLocalRenderer(video_track_) : 将main_wnd_作为sink插入到列表中, 通过video_track拿到VCMcapture, 再通过vcmCapture拿到broadcaster, 将main_wnd_ 插入列表中.
-
pc_->SetRemoteDescription() : 将视频编码器插入到列表中.
调用本地渲染将sink插入到broadcaster的调用栈:
addrender()
VideoTrack::AddOrUpdateSink()
VideoTrackSource::AddOrUpdateSink()
TestVideoCapture::AddOrUpdateSink()
VideoBroadcaster::AddOrUpdateSink()
VideoSourceBase::AddOrUpdateSink()
将视频编码器插入到broadcaster的调用栈:
PeerConnection::SetRemoteDescription()
...
PeerConnection::DoSetRemoteDescription()
PeerConnection::AppliRemoteDescription()
PeerConnection::UpdateSessionState()
PeerConnection::PushdownMediaDescription()
BaseChannel::SetRemoteContent()
... // 信令线程切换到工作线程
VideoChannel::SetRemoteContent_w()
WebRtcVideoChannel::SetSendParameters()
WebRtcVideoChannel::ApplyChangedParams()
WebRtcVideoChannel::WebRtcVideoSendStream::SetSendParameters()
WebRtcVideoChannel::WebRtcVideoSendStream::SetCodec()
WebRtcVideoChannel::WebRtcVideoSendStream::RecreateWebRtcStream()
internal::VideoSendStream::SetSource()
VideoStreamEncoder::SetSource()
VideoSourceSinkController::SetSource()
WebRtcVideoChannel::WebRtcVideoSendStream::AddUpdateSink()
...
VideoTrack::AddOrUpdateSink()
VideoTrackSource::AddOrUpdateSink()
test::TestVideoCapture::AddOrUpdateSink()
VideoBroadcaster::AddOrUpdateSink()
VideoSourceBase::AddOrUpdateSink()
WebRtcVideoChannel::
WebRtcVideoSendStream::
视频分发架构
通过上层api可以直接在session层创建VideoTrack, VideoTrack内部包含VideoTrackSource;
引擎层是在媒体协商(setLocalDescription、setRemoteDescription)的时候进行构造的, 同时也会根据需要去访问设备层, 例如VCMCapture初始化的时候就会访问设备层;
VideoBroadcaster是在VCMCapture创建的时候构造出来的;
插入sink_pair到broadcaster中的流程:
-
set local Renderer的时候,将视频渲染器对象插入broadcaster中
-
媒体协商调用setRemoteDescription时, 将VideoStreamEncoder对象插入broadcaster中
-
video Capture采集到视频的时候通过OnFrame函数交给broadcaster去分发给不同的接收者.
-
编码好的数据会交给PacedSender进行平滑处理,然后交给网络层发送出去
总结
-
broadcaster是在创建capture的时候被构造出来,此时里面没有要接收视频的接收者.
-
上层调用接口设置本地渲染器的时候, 本地渲染器作为一个接收者被加入到broadcaster中, 调用过程大致是 track->source->capture->broadcaster.
-
当进行媒体协商调用setRemoteDescription时, 将VideoStreamEncoder对象作为视频接收者插入到broadcaster中.
-
videoCapture通过On Frame 函数将视频数据传给broadcaster, broadcaster在分发给接收者列表中的所有接收者.
-
编码器将编码后的数据交给PacedSender进行平滑处理后,再通过网络层发送出去.