本文是从Webrtc实际应用的方面介绍如何快速理解Webrtc的源码。Webrtc是用于web的实时通信框架,也可以直接使用Google开源的Webrtc实现来开发非Web的APP。要理解如何使用webrtc的源码,最好是先懂得Webrtc通信的流程
需要掌握Webrtc的js部分的 PeerConnection,js部分的接口及方法如RTCPeerConnection,setLocalDescription、setRemoteDescription、createOffer、createAnswer 等,这些是理解源码的关键。
WebRTC 源码作为 Chromium 的一部分,更新速度非常快,这得益于 Google 对音视频通信的大力推广。WebRTC 源码的结构也变化很快,主要体现在以下几方面:
比较源码版本 m50 和 m66,在编译工具上发生了变化。老版本是通过 GYP 来生成 ninja 文件,新版本是通过 gn 生成 ninja 文件。
在目录结构上发生了变化,老版本中支持的一些功能在新版本中删除了。
随着 c++11,c++14,c++17 新标准的推出,WebRTC 在新版本中逐渐支持了新标准中的语法功能,使得代码变得更简洁、易维护。
目前手上有一份而 windows 版本的 m66 版本代码和一份 linux 版本的 m73 代码,这两个版本在目录结构上差异不大,在实现上有一些差异。比如,m73 版本为 BaseChannel 类抽象了一个 ChannelInterface 接口类。由于 WebRTC 代码下载不是很方便,所以本文后续会交替用 m66 和 m73 版本。
作为技术人员的我们,一是要理解 WebRTC 实现的原理,这样可以应对不断地变化。二是要跟踪最新的实现,将最新技术不断的引入到我们的产品中。
本文福利, C++音视频学习资料包、技术视频,内容包括(音视频开发,面试题,FFmpeg ,webRTC ,rtmp ,hls ,rtsp ,ffplay ,srs)↓↓↓↓↓↓见下面↓↓文章底部↓↓
因为Webrtc源码比较庞大,以下列出了比较关键的模块:
如果按照通常层次化的思维来组织,从下到上,大概分以下几个层次:
OS 跨平台适配、硬件设备访问、第三方库 Wrapper 层
包括网络层、操作系统 API 的跨平台封装,音频设备、视频设备封装,音频、视频 codec,DTLS 的第三方实现等。
网络传输层
这里包括 candidate 收集,stun/turn 协议的实现,dtls、rtp 网络连接的建立,sctp 连接的建立等。
通道层
主要包含传输通道也就是 BaseChannel 层 和 媒体通道 也就是 MediaChannel 层。BaseChannel 是和 PeerConnection、Transport 层对接。MediaChannel 实现其实在音视频引擎里面,是 BaseChannel 和引擎的桥梁。
RTP_RTCP 主要是流控
Audio Engine、Video Engine 是音视频引擎层,音视频处理。
音视频编解码器,这也是 WebRTC 自己的一个抽象,真正的编解码库还是依赖第三方库。
PeerConnection、MediaStream 主要是对 jsep 协议的实现。
PeerConnectionInterface 是一个对外抽象接口类设计。
Webrtc代码的目录结构说明:
上面我们对源码中的目录做了一个概要介绍,每一个目录又包含了很多功能。如果要是把每个目录都展开讲,那么 WebRTC 的完整架构介绍也就完成了,这显然是不可能的,后续章节会一一展开,详细探讨。本节,我们重点介绍一下 pc 和 module 目录。
上面我们对源码中的目录做了一个概要介绍,每一个目录又包含了很多功能。如果要是把每个目录都展开讲,那么 WebRTC 的完整架构介绍也就完成了,这显然是不可能的,后续章节会一一展开,详细探讨。本节,我们重点介绍一下 pc 和 module 目录。
PeerConnection
PeerConnection 的主要实现逻辑就是在 WebRTC 源码的 pc 目录下。
一切都从 PeerConnectionFactory 和 PeerConnection 开始,对外提供 PeerConnectionFactoryInterface 和 PeerConnectionInterface 两个接口类。Factory 类,顾名思义就是创建 PeerConnection 的,下来我们只讨论 PeerConnection。
也许你已经非常熟悉 WebRTC 的 JavaScript 接口。比如,RTCPeerConnection,setLocalDescription、setRemoteDescription、createOffer、createAnswer 等,没错这些。JavaScript 接口的 Native 实现就是在 PeerConnection 中完成的,它也有对应的一套接口。JavaScript 这套接口实现规范是JSEP。 可以说是把这套规范的模型都给实现了。
WebRTC 终端之间的通信协议是 ICE 协议,书包格式采用 SDP 协议。PeerConnection 实现了 SessionDescription 的逻辑。
PeerConnection 抽象了 RtpTransceiver,RtpSender、RtpReceiver 模型,对应了 sdp 中描述的媒体的实现。
WebRTC 将逻辑功能独立、内聚性、复用性强的部分单独抽象为模块。模块在 WebRTC 源码的 modules 目录下,主要是音视频设备、codec、流控等,这里不一一列举了。
Module 抽象了一个接口,源码实现在 modules/include/module.h 中,代码如下:
namespace webrtc{
class Module {
public:
virtual int64_t TimeUntilNextProcess() = 0;
virtual void Process() = 0;
virtual void ProcessThreadAttached(ProcessThread* process_thread) {}
protected:
virtual ~Module() {}
};
} // namespace webrtc
一共三个函数,相对简单,主要是为那些需要定时处理一些任务的模块提供一个统一的抽象。对于集成了 webrtc::Module 类的模块,使用的时候,需要调用 ProcessThread 的 RegisterModule 和 DeRegisterModule 方法向模块执行线程注册和反注册模块。我相信大家都知道,控制、调度逻辑是最复杂易错的,实现起来也是最枯燥乏味,设计不好,很容易重复实现很多代码。所以 WebRTC 索性都封装起来,实现者只需要被动的实现功能逻辑即可。
关于函数的具体功能,头文件的注释写的非常详细,可以参考。
原文链接:Webrtc 源码分析 - 资料 - 我爱音视频网 - 构建全国最权威的音视频技术交流分享论坛
本文福利, C++音视频学习资料包、技术视频,内容包括(音视频开发,面试题,FFmpeg ,webRTC ,rtmp ,hls ,rtsp ,ffplay ,srs)↓↓↓↓↓↓见下面↓↓文章底部↓↓