突然有点感慨,代码越挖越深,类结构图越画越庞大,要理清楚的东西也就越来越多.
webrtc android AndroidSource类的分析-Source和Sink的关系
private VideoTrack createVideoTrack(VideoCapturer capturer) {
surfaceTextureHelper =
SurfaceTextureHelper.create("CaptureThread", rootEglBase.getEglBaseContext());
videoSource = factory.createVideoSource(capturer.isScreencast());
capturer.initialize(surfaceTextureHelper, appContext, videoSource.getCapturerObserver());
capturer.startCapture(videoWidth, videoHeight, videoFps);
localVideoTrack = factory.createVideoTrack(VIDEO_TRACK_ID, videoSource);
localVideoTrack.setEnabled(renderVideo);
localVideoTrack.addSink(localRender);
return localVideoTrack;
}
通过断点不断到监控,我们可以发现,我们创建Track到代码如下:
rtc::scoped_refptr CreateVideoTrack(const std::string& a1, VideoTrackSourceInterface* a2) override {
MethodCall2, const std::string&, VideoTrackSourceInterface*> call(c_, &C::CreateVideoTrack, std::move(a1),
std::move(a2));
return call.Marshal(RTC_FROM_HERE, signaling_thread_);
}
上面到代码有一个巧妙的地方,那就是:
把创建Track的方法实现全部放到了signal_thread线程中去进行了实现.
具体的实现方式,大家可以参考我写的这篇文章,也比较简单:
https://blog.csdn.net/zhangkai19890929/article/details/82692067
创建track是PeerConnectionFactoryProxyWithInternal,这个类继承于PeerConnectionFactoryInterface.
这里稍微多说点,这里运用的是代理模式的设计思维。
所以PeerConnectionFactoryProxyWithInternal肯定会继承于PeerConnectionFactoryInterface,并且有一个PeerConnectionFactoryInterface的成员,在实现PeerConnectionFactoryInterface接口方法的时候,具体是调用成员去实现.
注意 PeerConnectionFactoryProxyWithInternal是通过宏定义实现的,在peerconnectionfactoryproxy.h文件中.
通过跟踪代码,createVideoTrack最终被执行的位置是在:
peerconnectionfactory.cc文件的CreateVideoTrack方法中:
rtc::scoped_refptr PeerConnectionFactory::CreateVideoTrack(
const std::string& id,
VideoTrackSourceInterface* source) {
RTC_DCHECK(signaling_thread_->IsCurrent());
rtc::scoped_refptr track(
VideoTrack::Create(id, source, worker_thread_));
return VideoTrackProxy::Create(signaling_thread_, worker_thread_, track);
}
借助这个流程图,我们能大致的看明白,track和source的各个层级的依赖关系.
后面的很多重要细节我们依然会单独的写文章进行分析.
到这里我们基本弄明白了track和source ,source和sink到关系,接下来我们接着分析:
localVideoTrack.addSink(localRender);
分析这段核心代码,—其实到这里基本可以猜测出来,track添加sink,应该是添加到了source中去了,source和track都继承了VideoSourceInterface的接口.
这个接口定义了添加和移除sink的方法.
个人猜测先由track添加,但是具体执行的是source,source传递给了videoBroadcast了,应该是简单的事件传递.
ok,我们来具体跟踪下代码: