下图是 WebRTC APM 内部模块的数据流程图:
从图中可以看出,APM 其实也为插件化做了准备,但是只在近端信号的尾部、远端信号的头部。从 APM 构造函数上也可以看出来:
滤波/均衡,可以方便的实现一个 CustomProcessing 的 render_pre_processor。
其他的优化,遵循轻量化/插件化的理念,没有现成的插件接口,我们可以创造新的插件接口,如啸叫抑制,以及 AECM 优化的部分算法。
但 APM 仍然会有很多没办法插件化的,只能修改 light-rtc 仓库,如 AECM Double Talk 优化等。
AMAM(Audio Mixer)的插件化,可以在不修改 light-rtc 的基础上,玩出很多花样:
播放本地文件;
借助语音检测算法,优化语音排序,从而选出更准确的语音做混音;
Mono 变成 Stereo,借助 HRTF,可以在多方同时说话时提高说话人辨识度和可懂度;
对 RTP 方案的回放,倍速回放时变速不变调;
……
FEC(Forward Error Correction),常见的修改:
调参,如冗余度、MaxFrames、Table 类型,包括固定参数和动态自适应调参两类,已有的插件接口 WebRTC::FecControllerFactoryInterface 即可满足;
RSFEC,需要创造新的插件接口;
Opus Inband FEC。WebRTC 动态配置的 Opus FEC 参数,不能很好的解决弱网时声音卡顿问题。这时,一个办法是把 Opus 独立成仓库,直接修改 Opus 编码器。
CC(Congestion Control),包含两个方面,一个是 CC 算法本身,一个是 CC 关联模块。
算法本身,可以用不同的算法实现,如 WebRTC 默认的 goog_cc,也可以是 BBR,甚至是满足 WebRTC::NetworkControllerFactoryInterface 接口的外部插件。
关联模块:
带宽分配:不同场景可能不一样,如视频会议里,需要“保音频、保屏幕”。可以通过 rtc::BitrateAllocationStrategy 实现插件化。
Pacer 调优:对于屏幕内容,I帧往往非常大,WebRTC 的 2.5 倍的发送带宽,会导致巨大的首帧时间。具体解法见仁见智。
……
Android、iOS、Mac,WebRTC 都提供了默认的实现,虽然有少量 Bug,但是基本满足需求。
Windows 平台,早期 WebRTC 提供了 D3D 的实现,最新版已经剔除,我们可以在 lrtc-plugin 仓库实现自己的 D3D,或者其他的渲染,如 QT OpenGL。
VideoProcessWebRTC 并没有提供视频前处理(如:美颜)、后处理(如:超分辨率)的接口,但是我们完全可以像 rtc::BitrateAllocationStrategy 一样,创造 VideoProcessInterface 接口, 并在 lrtc-plugin 仓库里实现。
让 VideoProcessInterface 同时继承 Sink 和 Source 接口,可以方便的把多个对象串联起来。 其他 & Bugfix
其他核心模块,如 JitterBuffer、ICE 等,目前接触的主要是 Bugfix,还没有发现自己定制重写的必要。
Bugfix,往往只能修改 light-rtc 仓库。一方面,是尽量把 Bugfix 内聚成函数,减少对已有代码的修改;另一方面,尽量把 Bugfix 贡献到开源社区(Issue Tracker),既为开源社区做了贡献,也彻底避免了升级的冲突。