0
点赞
收藏
分享

微信扫一扫

WebRTC源码级深度解析,进阶大厂高级音视频开发者

DYBOY 2022-02-10 阅读 120

​​立即下载​​

WebRTC源码级深度解析,进阶大厂高级音视频开发者_音视频

​​立即下载​​

当下音视频行业发展火爆,WebRTC作为优秀的音视频开源库,被大范围的应用在各种音视频业务中,对于高级音视频开发者来说,需要具备业务适用性改造能力。对于音视频开发者来说,学习、分析WebRTC,从中借鉴好的经验,是极具价值的。


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 实现的原理,这样可以应对不断地变化。二是要跟踪最新的实现,将最新技术不断的引入到我们的产品中。

如果按照通常层次化的思维来组织,从下到上,大概分以下几个层次:

  • 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 是一个对外抽象接口类设计。

源码目录结构介绍

本节,我们以 m66 版本的代码为例,讲解一下代码的目录结构。

api              ;提供了对外的接口,音视频引擎层和 Module 直接的接口。
audio ;音频流的一部分抽象,属于引擎的一部分逻辑。
base ;这一部分还没有学习到,属于 Chromium 项目的一部分,貌似 WebRTC 中用的并不多。
build ;编译脚本。这里需要注意的是,不同平台的代码在下载的时候,获取的工具集是不一样的。
build_overrides ;编译工具。
buildtools ;编译工具链。
call ;主要是媒体流的接口抽象。为媒体引擎和 codec 层提供桥接。这里说的媒体流是 RTP 流。pc 层也抽象了媒体流,那是编码前、或者解码后。
common_audio ;音频算法实现,比如 fft。
common_video ;视频算法实现,比如 h264 协议格式。
data ;测试数据
examples ;WebRTC 使用的例子。提供了 peerconnection_client、peerconnection_server、stun、turn 的 demo。
help ;没有学习到。
infra ;没有学习到。
logging ;WebRTC 的 log 库。
media ;媒体引擎层,包括音频、视频引擎实现。
modules ;WebRTC 把一些逻辑比较独立的抽象为 Module,利于扩展维护。
ortc ;媒体描述协议,类似 sdp 协议。
out ;build 输出目录,这是 webrtc 官方编译指导中示范目录。
p2p ;主要是实现 candidate 收集,NAT 穿越。
pc ;实现 jsep 协议。
resources ;测试数据
rtc_base ;包括 Socket、线程、锁等 OS 基础功能实现。
rtc_tools ;网络监测工具、音视频分析工具。很多工具都是脚本实现。
sdk ;主要是移动端相关实现。
stats ;WebRTC 统计模块实现。
style-guide ;编码规范说明
system_wrappers ;OS 相关功能的封装,比如 cpu、clock 等。
test ;单元测试代码实现,用 gmock
testing ;gmock、gtest等源码,属于整个 Chromium 项目。
third_party ;第三方库依赖。比如,boringssl,abseil-cpp,libvpx等
tools ;公共工具集,整个 Chromium 项目依赖的。
tools_webrtc ;WebRTC 用到的工具集。比如代码检查 valgrind 的使用。
video ;视频 RTP 流的抽象接口,属于视频引擎的一部分。

上面我们队源码中的目录做了一个概要介绍,每一个目录又包含了很多功能。如果要是把每个目录都展开讲,那么 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 中描述的媒体的实现。

Module

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 索性都封装起来,实现者只需要被动的实现功能逻辑即可。

关于函数的具体功能,头文件的注释写的非常详细,可以参考。


举报

相关推荐

0 条评论