Webrtc 线程,信号-槽,Msg queue

通信机制:invoke/posttask , sink 
Invoke是同步,在另一个线程执行function.
posttask是异步,在另一个线程执行function

接收信号: port是发送信号的类,SignalCandidateReady是信号,OnCandidateReady是callback
port->SignalCandidateReady.connect(
      this, &BasicPortAllocatorSession::OnCandidateReady);
发送信号
void Port::AddAddress {
    SignalCandidateReady(this, c);
}

图中每一个矩形框都代表了一个线程,我们这里列出了 11 个线程,当然这些是最主要的线程。线程之间的通信要么是通过图中标出的 Packet 队列,要么是通过 WebRTC 的 MessageQueue 来实现的。图中蓝色的线和橘色的线分别标出了数据包输出和输入时,在各个线程流向情况。

线程功能说明

PeerConnectionFactory的Initialize必须在signaling_thread_线程上执行,并且此处还需要阻塞的获取执行结果,以便根据结果确定是否要执行后续的代码
创建了网络管理对象BasicNetworkManager,
创建了默认的Socket工厂类对象BasicPacketSocketFactory,
创建了通道管理类ChannelManager并初始化

3个重要线程:
– Thread* signaling_thread:信令线程,示例工程中为UI主线程(当然也可以不是主线程);
– Thread* worker_thread:工作者线程,负责耗时操作;
– Thread* network_thread:网络线程,处理网络相关的操作;
7个音视频相关对象(5个音频相关,2个视频相关),用于创建多媒体引擎:
– scoped_refptr<AudioDeviceModule> default_adm:音频设备模块adm;
– scoped_refptr<AudioEncoderFactory> audio_encoder_factory:音频编码器工厂;
– scoped_refptr<AudioDecoderFactory> audio_decoder_factory:音频解码器工厂;
– scoped_refptr<AudioMixer> audio_mixer:混音器;
– scoped_refptr<AudioProcessing> audio_processing:音频处理器;
– unique_ptr<VideoEncoderFactory> video_encoder_factory:视频编码器工厂;
– unique_ptr<VideoDecoderFactory> video_decoder_factory:视频解码器工厂;

WebRTC是个多线程架构的程序,有3个基础的线程:信令线程,工作者线程,网络线程。
对于应用层而言,得到的实体对象是一个Proxy对象,也即在用户和实际提供功能的类之间插入了一层代理层。

  • 信令线程(Signal Thread)
    一般是工作在 PeerConnection 层,主要是完成控制平面的逻辑,用于和应用层交互。比如,CreateOffer,SetRemoteSession 等接口都是通过 Signal threa 完成的。默认是采用 PeerConnectionFactory 初始化线程作为信令线程。
  • 工作线程(Worker Thread)
    主要是工作在媒体引擎层(media engine),具体工作如下:
    • 音频设备初始化
    • 视频设备初始化
    • 流对象的初始化
    • 从网络线程接收数据,传给解码器线程
    • 从编码器线程接收数据,传给网络线程

notes:音视频传输和av传输是分开的。

  • 网络线程(Network thread )
    主要是工作在传输(transport)层,具体工作如下:
    • Transport 的初始化
    • 从网络接收数据,发送给 Worker thread
    • 从 Worker thread 接收数据,发送到网络
  • 视频采集线程
    主要工作是完成视频原始数据的采集。在 Windows 上,这个线程是由directshow 提供。视频数据接收函数是 CaptureInputPin::Receive,实现文件是 http://sink_filter_ds.cc
  • 视频编码线程
    主要工作是对视频的原始数据进行编码,从 Capture 接收 VideoFrame,然后调用编码器执行编码逻辑,将编码后的视频数据发送到 PacerSender。视频编码线程是通过 TaskQueue 实现的,线程名称是 EncodeThread。具体实现位置是 VideoStreamEncoder::TaskQueue,文件名是 video/video_stream_encoder.h。
  • 视频解码线程
    主要工作就是视频解码,具体如下:
    • 从工作线程接收数据,然后调用视频解码器执行解码逻辑。
    • 将解码后的视频数据发送给渲染线程。

具体实现的线程函数是 VideoReceiveStream::DecodeThreadFunction ,实现文件是 video/http://video_receive_stream.cc

  • 视频渲染线程
    主要工作是将解码后的视频图像发送给上层应用,进行渲染。具体实现类是
    IncomingVideoStream::NewFrameTask,通过 rtc::QueuedTask 实现的。
  • 音频采集线程
    主要工作是音频输入采集,比如采集麦克风声音。在 Windows 平台的线程函数 是 AudioDeviceWindowsCore::WSAPICaptureThread。线程名称是“webrtc_core_audio_capture_thread”,实现文件是
    http://audio_device_core_win.cc
  • 音频编码线程
    主要工作是从音频采集线程接收数据,调用音频编码器进行编码,然后将编码后的数据发送给 PaceSender。实现类是 Channel,通 rtc::TaskQueue 实现的。线程名称是 call_worker_queue,实现文件是 audio/channel.h。
  • 音频渲染线程
    音频渲染线程也是音频解码线程。在 Windows 平台下,线程函数是 AudioDeviceWindowsCore::WSAPIRenderThread,线程名称是“webrtc_core_audio_render_thread”。
  • 发送控制线程
    主要工作是定时发送音频、视频 rtp 包,线程名称是 SendControllerThread。

Call类分析:

Thread

这里写图片描述

这里写图片描述

多线程消息传递

这里写图片描述

 msgqueue:

这里写图片描述

 由图可见,调用Start()后会创建一个新线程,在线程中循环遍历module,执行module的process(), 遍历queue, 执行task的run(), 然后调用wake_up->Wait()进入休眠,等待下一次唤醒。

我们再来看一下ProcessThread的RegisterModule函数:

void ProcessThreadImpl::RegisterModule(Module* module) {
  modules_.push_back(ModuleCallback(module));
  wake_up_->Set();
}
Call中有两个跟线程有关的成员module_process_thread_和pacer_thread_

参考:WebRTC学习进阶之路 --- 十四、源码分析之WebRTC中的线程详解-ThreadManager&Thread_SmallBottle-CGWLMX的博客-CSDN博客

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值