网易云信音视频处理引擎最佳实践

导读:随着 RTC 技术的广泛应用以及场景不断丰富,越来越多的音视频特性加入到 RTC 中,这也带来了一些问题:1. RTC SDK 包体积不断增大;2. 开启音视频特性导致在中低端设备上 RTC 指标下降。为此,网易云信设计和研发了 AVProcessEngine 框架,旨在解决音视频算法在运行中所遇到的问题。

作者:bili
来源:网易云信

01 背景

如今,RTC 技术已经在人们的工作和生活的方方面面得到广泛应用,例如视频会议、娱乐直播、远程医疗等。不同的业务场景对音视频的需求也不尽相同,例如娱乐直播需要美颜功能,而会议场景需要虚拟背景功能。为客户提供一套完整音视频特性的 RTC SDK,可能会对不同场景的客户造成功能和包体积上的冗余(尤其是包体积,这是非常重要的交付指标)。此外,在实际使用中,由于 RTC 支持的终端平台众多(如 Windows、Android、iOS 和 macOS 等),客户设备的性能差异(尤其是在海外市场,中低端设备占据主要市场),复杂的音视频特性往往会导致中低端设备上的帧率、延时、卡顿率等 RTC 指标下降。

为了解决在实践过程中碰到的这些问题,我们设计和研发了音视频处理引擎(AVProcessEngine),希望为客户提供更好的体验。

02 AVProcessEngine 音视频引擎

云信的 RTC 音视频处理的流程大致如下:

网易云信音视频处理引擎最佳实践
  • 发送端:首先通过“采集”模块从摄像头或麦克风采集音视频数据,然后将数据传入“前处理”模块,经过美颜、虚拟背景、AI 降噪等算法处理后,再将数据送入“编码”模块进行数据压缩,如 H264、H265 等。最后通过“网络传输”模块将压缩后的数据传输给服务器进行分发。
  • 接收端:从“网络传输”模块接收压缩后的音视频数据,送入“解码”模块进行解码,解码为音视频裸数据,如 PCM 或 YUV。然后传入“后处理”模块,经过超分、视频增强等算法处理后,最终送入“播放”模块进行播放和渲染。

在上述的方案中,NERTC SDK 集成了所有的功能模块以及音视频算法,一起打包提供给用户,这样的方式虽然在音视频算法特性上保持完整,但也会导致不需要特定音视频功能的客户出现功能和包体积上的冗余。

我们设计 AVProcessEngine 音视频引擎的目标之一就是将 NERTC SDK 与音视频算法的解耦:NERTC SDK 保留最基本的音视频通话功能,音视频算法从基础 SDK 包中独立出来。当客户需要特定的音视频特效时,再提供相应的音视频算法库给用户集成。

增加 AVProcessEngine 后,NERTC SDK 整体框架做了如下调整:

网易云信音视频处理引擎最佳实践

AVProcessEngine 作为 NERTC SDK 的子模块,NERTC SDK 中的其他模块不直接调用音视频算法,所有对音视频数据的操作都通过 AVProcessEngine 来进行。

音视频算法则从 NERTC SDK 中独立处理,以插件的形式存在,形成一个音视频算法库的集合。

AVProcessEngine 的框架如下图:

网易云信音视频处理引擎最佳实践

为了规范其他功能模块调用 AVProcessEngine 行为,AVProcessEngine 提供了统一的接口:

  • 初始化接口:设置音视频算法类型,以及初始化的一些工作。
  • 状态查询接口:获取当前的运行状态和信息等。
  • 运行接口:传入和输出音视频数据。
  • 销毁接口:释放引擎资源。

其他模块则通过上述的接口,通知 AVProcessEngine 调用相应的音视频算法、设置算法参数、传入音视频数据并获取处理后的结果。

接下来,我们将介绍一下 AVProcessEngine 内部的各个模块,以及如何实现音视频算法的插件化和算法的动态调整。

 音视频插件加载模块 

音视频算法以插件的形式存在,所以 NERTC SDK 使用某个音视频算法时,首先就是要通过加载模块来加载相应的插件。AVProcessEngine 中的音视频插件加载模块与音视频算法插件的实现是相互匹配,我们采用了类似 OpenMAX 的接口,作为插件实现和插件运行的规范。OpenMAX 是一套 C 语言定义的多媒体加速接口,支持大量的音视频数据的处理。网上对这方面的资料较多,这里不再赘述。

在介绍 AVProcessEngine 插件加载前,首先简单介绍一下音视频插件是如何做到插件化的。

音视频算法插件的实现

音视频算法一般都有参数设置和获取,音视频数据处理的功能,所以我们在 OpenMAX 规范的基础上,设计封装了 OMXComponent 的基类,定义了音视频算法处理的通用接口,每个插件都继承和实现 OMXComponent 类的功能,OMXComponent 中定义大致如下:

  • 参数设置接口:设置算法参数,不同算法有不同的参数,最终影响音视频数据处理的效果。
  • 参数获取接口:获取运行中的算法的参数值。
  • 音视频数据处理接口:对传入的音视频数据进行处理,并返回处理后的结果。
  • 状态获取接口:获取当前状态,判断算法是否处于运行状态。
网易云信音视频处理引擎最佳实践

以美颜算法为例,AVProcessEngine 中需要实现的接口包括:

  • setParameter接口:用于设置美颜特效(如美白)等级。
  • getParameter接口:用于获取当前美颜特效等级。
  • processVideoFrame 接口:用于实现原始音视频帧处理功能,处理后返回带有美颜特效的视频帧。
  • getState接口:用于获取当前插件状态,例如正在运行或空闲等信息。

一旦实现了 OMXComponent 的接口,一个插件的功能基本上就封装完成了。同时每个插件都需要对外开放 CreatePlugin 和 DestroyPlugin 接口,用于创建和销毁插件实例。

介绍完音视频算法插件化的,下面介绍一下 AVProcessEngine 是如何将插件加载进来的。

AVProcessEngine加载插件的流程

AVProcessEngine 采用动态内存的方式来实现插件加载(不同平台的实现可能略有不同)。每个插件将对外开放的 CreatePlugin 和 DestroyPlugin 接口以函数指针的形式写入 AVProcessEngine 可以访问的动态内存中,AVProcessEngine 根据插件名字查找相应内存中的函数指针,如果获取到对应的函数指针,则调用 CreatePlugin 函数创建算法插件,插件加载成功。如果无法获取到对应的函数指针,则表示插件加载失败。

网易云信音视频处理引擎最佳实践

算法插件创建完成后,AVProcessEngine 则会遵循 OpenMAX 接口规范,执行音视频算法,实现传参、获取状态和生成特效等操作。如果插件未加载成功,NERTC SDK 还是调用插件算法的话,AVProcessEngine 内部也做了容错处理,会直接返回原始视频帧,并向上层反馈或者在日志系统中记录,方便问题的定位。

 音视频算法运行管理模块 

音视频算法运行管理模块的主要功能是在运行时动态调整算法,尽可能地提升 NERTC 的各项性能指标。

对于算法动态调整功能,首先需要音视频算法团队综合评估算法性能和质量后,设置不同档位的算法,比如有效果优先的档位,有性能优先的档位等。管理模块根据当前运行的状况,实时切换算法档位,比如性能不足时,选择性能优先档位,性能完全满足要求时,选择质量最优档位,充分发挥设备性能,让用户有更好的体验。

音视频算法动态调整策略

算法动态调整的策略是统计各个功能模块的耗时情况,判断是否会引起 NERTC 指标下降,实时调整相应模块中的音视频算法。

以“视频前处理模块”为例,假设 NERTC 设置的帧率为 30FPS,在“前处理”模块中开启美颜、虚拟背景和视频降噪等算法情况下,“前处理”可能会成为整个 RTC 视频 Pipeline 的瓶颈,从而拉低后续处理模块的帧率,导致整体 RTC 的指标下降。

如下图,AVProcessEngine 监测耗时信息:前处理的总耗时 TotalTime、美颜耗时 time1、虚拟背景耗时 time2、视频降噪耗时 time3。

网易云信音视频处理引擎最佳实践

AVProcessEngine 根据获取到的耗时情况,调整前处理内部视频算法的档位,大致的流程如下:

网易云信音视频处理引擎最佳实践

如果前处理的总耗时(TotalTime)大于 33ms,并高于一定的阈值,则表示无法满足实时要求,则进入算法档位的下调流程:首先对开启的算法做耗时从大到小的排序,得到耗时最大的算法,并判断该算法是否支持档位下调,如果支持则下调算法档位,如果不支持下调,则判断第二排序的算法是否支持档位下调,以此类推,如果所有的算法已经调整到最低档位仍然无法满足实时要求,则不再做调整。

如果前处理的总耗时(TotalTime)小于 33ms,并低于一定的阈值,则认为可以尝试算法档位上调,这时进入算法档位上调流程,与算法档位下调流程类似,主要区别是算法上调优先调整耗时较小的算法。

以上是模块内部算法调整的策略。AVProcessEngine 也支持不同模块间动态调整,例如前处理模块在编码模块之前,如果编码模块成为性能的瓶颈,即使前处理模块性能足够,但对最终的效果没有太大影响,反而增加了一些无效的功耗损失。AVProcessEngine 在这种情况下,一般会采取相对较柔和的丢帧等策略,释放这部分无效操作和资源,对整体的 RTC 效果能带来一些提升。

网易云信音视频处理引擎最佳实践

日志上报模块 

日志上报模块,主要是对 AVProcessEngine 中的关键节点进行日志埋点上报,例如插件是否加载成功,如果失败的话,失败的原因是什么等信息,为后续问题的定位和解决提供必要的帮助。

总结

开头提到的包体积问题和运行时 RTC 指标下降的问题,AVProcessEngine 都提出了一套可行的方案。AVProcessEngine 通过音视频算法插件化,将 NERTC SDK 与音视频算法解耦,从而解决了音视频算法引起的包体积问题。通过音视频算法的动态调整策略,提升 RTC 在中低端设备上延时,卡顿,流畅性等指标。

未来展望

目前,我们主要收集和统计运行过程中音视频算法的耗时,并根据算法的耗时情况实时调整算法的档位。后续,我们将增加对设备其他信息的统计,例如 CPU 占用率、GPU 占用率等,以便为算法调整提供更全面和多维度依据。此外,我们还将进一步细化音视频算法的档位,使算法档位之间的切换更加平滑和流畅。

版权声明:本文内容转自互联网,本文观点仅代表作者本人。本站仅提供信息存储空间服务,所有权归原作者所有。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至1393616908@qq.com 举报,一经查实,本站将立刻删除。

(0)

相关推荐

发表回复

登录后才能评论