7 月 31 日,阿里云视频云受邀加入由凋谢原子开源基金会、Linux 基金会亚太区、开源中国独特举办的寰球开源技术峰会 GOTC 2021 ,在大会的音视频性能优化专场上,分享了开源 FFmpeg 在性能减速方面的实战经验以及端云一体媒体零碎建设与优化。

家喻户晓,FFmpeg 作为开源音视频解决的瑞士军刀,以其开源收费、功能强大、不便易用的特点而非常风行。音视频解决的高计算复杂度使得性能减速成为 FFmpeg 开发永恒的主题。阿里云视频云媒体解决零碎宽泛借鉴了开源 FFmpeg 在性能减速方面的教训,同时依据本身产品和架构进行了端云一体媒体零碎架构设计与优化,打造出高性能、高画质、低延时的端云协同的实时媒体服务。

阿里云智能视频云高级技术专家李忠,目前负责阿里云视频云 RTC 云端媒体解决服务以及端云一体的媒体解决性能优化,是 FFmpeg 官网代码的维护者及技术委员会委员,参加过多个音视频开源软件的开发。

本次分享的议题是《从 FFmpeg 性能减速到端云一体媒体系统优化》,次要介绍三个方面的内容:

一、FFmpeg 中常见的性能减速办法
二、云端媒体解决零碎
三、端 + 云的协同媒体解决零碎

FFmpeg 中常见的性能减速办法

音视频开发者以后次要面临的挑战之一是对计算量的高需要,它不只是单任务算法优化,还波及到很多硬件、软件、调度、业务层,以及不同业务场景的挑战。其次端、云、不同设施、不同网络,这些综合的复杂性现状,要求开发者要做系统性的架构开发与优化。

FFmpeg 是一个十分弱小的软件,包含音视频的解码编码、各种音视频的 Filter 、各种协定的反对。作为一个开源软件 FFmpeg 次要的 License 是 GPL 或者 LGPL,编程语言是 C 和汇编。它还提供了很多关上即用的命令行工具,比方转码的 ffmpeg 、音视频解析的 ffprobe、播放器 ffplayer。其外围的 Library 有负责编解码的 libavcodec、解决音视频的 libavfilter 、反对各种协定的 libavformat。

FFmpeg 开发社区中,音视频性能优化是一个永恒的主题,其开源代码里也提供了十分多的经典性能优化的实现办法,次要是通用减速、CPU 指令减速、GPU 硬件加速。

通用减速

通用减速次要是算法优化、IO 读写优化、多线程优化。算法优化的指标是在不减少 CPU Usage 的前提下进步性能。最典型是编解码器的各种疾速搜索算法,它能够在精度只有多数损失的状况下,大幅优化编码速度。各种前后解决 Filter 的算法也有相似的办法,也能够通过算法合并来缩小冗余的计算,达到性能优化的目标。

下图是一种典型的降噪与锐化卷积模板,它须要做 3 乘 3 的矩阵卷积。咱们能够看到,这里的锐化模板跟平滑模板是相似的,对于同时要做降噪和锐化的操作,只有在平滑的模板的根底下面做减法能够达到锐化化模板的后果,能够缩小冗余的计算,晋升性能。当然算法优化也存在局限性,比方编解码算法有精度上的损失,还可能须要就义空间复杂度换取工夫复杂度。

第二种性能优化的办法是 IO 读写优化,常见办法是利用 CPU 预读取来改善 Cache Miss 。上图是通过两种读写的办法达到雷同的运算后果,按行读写的办法比按列读写快,次要起因是 CPU 在按行读写时可做预读取,在解决以后像素的时候,CPU 曾经预读本行的其余像素,能够大大减速 IO 读写的速度,进步性能。另外能够尽量减少 Memory Copy,因为视频解决 YUV 十分大,每读一帧对性能的损耗比拟大。

通用减速的多线程优化次要是利用 CPU 多核做多线程的并行减速来大幅晋升性能。上图中左下角的图表表明随着线程数的减少,性能晋升了 8 倍。随之也会产生一个问题,广泛被应用的多线程减速,线程数是不是越多越好呢?

答案是 No 。

首先,因为 CPU 核数限度,多线程期待和调度,多线程优化会碰到性能瓶颈。以左下角的图表为例,线程数等于 10 的减速比跟线程数等于 11 时十分靠近,能够看出多线程优化存在边际效应的递加,同时也会带来延时和内存耗费的减少(尤其是广泛应用的帧间多线程)。

第二,帧间(Frame level)多线程须要建设 Frame Buffer Pool 进行多线程并行,这须要缓冲很多帧,对于提早十分敏感的媒体解决,比方低延时直播、RTC ,会带来比拟大的负面效应。与之对应的是,FFmpeg 反对帧内(Slice level)的多线程,能够把一帧划分成多个 Slice,而后做并行处理,这样可能无效防止帧间的 Buffer 提早。

第三,当线程数增多,线程同步和调度的老本也会减少。以右下图的一个 FFmpeg Filter 减速为例,随着线程数的减少,CPU Cost 也在明显增加, 且图表曲线末端开始往上歪斜,这表明其老本的减少变得更显著。

CPU 指令减速

CPU 指令减速即 SIMD(单指令多数据流)指令减速。传统通用的寄存器和指令,一条指令解决一个元素。但一条 SIMD 指令能够解决一个数组中的多个元素,从而达到十分显著的减速成果。

当初支流的 CPU 架构都有对应的 SIMD 指令集。X86 架构 SIMD 指令包含 MMX 指令、SSE 指令、AVX2、AVX-512 指令。其中 AVX-512 的一条指令可解决 512 个 bits,减速成果非常明显。

FFmpeg 社区的 SIMD 指令写法包含内联汇编、手写汇编。FFmpeg 社区不容许应用 intrinsic 编程,起因是它对编译器的版本存在依赖,不同编译器编译出的代码及其减速成果也是不统一的。

尽管 SIMD 指令有好的减速成果,但它也存在肯定的局限性。

首先,很多的算法不是并行处理的,不能进行 SIMD 指令优化。

其次,编程难度比拟大。汇编编程的难度就要大些,另外 SIMD 指令对编程有一些非凡的要求,比方 Memory 对齐。AVX-512 要求 Memory 最好可能做到 64 字节对齐,如果没有对齐的话,可能会有性能上的损耗,甚至会引起程序的 Crash。

咱们看到不同的 CPU 厂商都在做指令集比赛,反对的位宽越来越多,从 SSE 到 AVX2 再到 AVX-512 ,位宽显著减少。那位宽是不是越宽越好?上图能够看到 X265 编码 AVX 512 绝对 AVX 2 的提速状况,AVX 512 的位宽是 AVX 2 位宽的两倍,但性能晋升实际上往往远达不到一倍,甚至达不到 10%。在某些状况下,AVX 512 的性能会比 AVX 2 还要低。

起因是什么呢?

首先,一次性的数据输出可能并没有 512 bits 这么多,可能只有 128 bits 或者是 256 bits。

第二,有很多的简单运算步骤(如编码器)不能做指令集的并行。

第三,AVX 512 功耗较高,会引起 CPU 的降频,导致 CPU 整体解决的速度会有所降落。咱们看上图的 X265 ultrafast 品位编码,AVX 512 的编码比 AVX 2 还要慢。(详见:https://networkbuilders.intel...)

硬件加速

FFmpeg 比拟支流的硬件加速是 GPU 减速。硬件加速接口分为两大块,一是硬件厂商提供不同的减速接口。英特尔次要提供 QSV 和 VAAPI 的接口,英伟达提供 NVENC、CUVID、NVDEC 、VDPAU,AMD 提供 AMF 和 VAAPI 的接口。二是不同的 OS 厂商提供不同的减速接口和计划,比方 Windows 的 DXVA2,安卓的 MediaCodec ,苹果的 VideoToolbox 。

硬件加速能够显著晋升媒体解决的性能,然而它也会带来一些问题。

第一,硬件的编码品质受限于硬件的设计及老本,硬件编码的品质往往是会比软件编码品质差。但硬件编码有非常明显的性能劣势,能够用性能去换编码品质。下图的例子可看出,硬件编码器静止搜寻的窗口比拟小,导致编码品质的降落。其解决办法是 HME 算法,在搜寻窗口比拟小的状况下,先把比拟大的 Picture 缩放到十分小的 Picture,在这个 Picture 上做静止搜寻,再逐级做搜寻和放大,这样能够显著进步静止搜寻的范畴,而后找到最匹配的块,从而改善编码品质。

第二,硬件加速的 CPU 和 GPU 的 Memory Copy 性能交互会带来性能的降落。

CPU 和 GPU 的交互不仅仅是简略的数据搬移过程,实际上要做对应的像素的格局转换,比方 CPU 是 I420 linear 格局,GPU 善于矩阵运算,采纳 NV12 Tiled 格局。

这种内存格局的转化,会带来显著的性能损耗。能够通过构建纯硬件的 Pipeline ,无效的躲避 CPU/GPU Memory 交互的问题。当 CPU 和 GPU 必须交互的状况下,能够采取 Fast Memory Copy 的形式,采纳 GPU 去做 Memory Copy ,减速这一过程。

下图是性能优化的总结大图。除了后面提到一些优化办法外,客户端上的媒体解决还有一些特殊性,比方手机 CPU 是大小核架构,线程调度如果调度到小核上,它的性能会显著比大核要差,导致性能的不稳固。

另外很多的算法不论如何优化,在某些机型上就是无奈跑通,这时要在业务策略下面做优化,比方制订黑白名单,不在反对名单的机器就不开启该算法。

云端媒体解决系统优化

对于媒体解决来说分为两大挑战,一是云端的老本优化,二是客户端设施适配及兼容。下图是云端媒体解决的典型零碎:包含单机层、集群调度层、业务层。

单机层包含 FFmpeg Pipeline 解决框架、编解码、硬件层。以云端转码零碎为例,它的外围技术指标包含画质、处理速度、延时、老本。画质方面,阿里云视频云独创了窄带高清的技术以及 S265 编码技术,能够显著改善编码画质。处理速度和延时优化方面,咱们宽泛借鉴 FFmpeg 性能减速办法,比方 SIMD 指令、多线程减速以及异构计算的反对。老本是一个比较复杂的零碎,它会包含调度层、单机层、业务层,须要进行疾速的弹性扩缩容,单机资源准确画像,缩小单任务的计算成本。

云端老本优化

云端老本优化的外围是围绕三条曲线去做优化,针对单任务理论资源耗费、单任务资源预估调配、总资源池这三条曲线别离做对应的优化。在优化过程中须要面对四个事实的问题:

第一,在视频云的业务里,业务多样性的趋势会越来越显著,业务包含点播、直播、RTC、 AI 编辑部、云剪辑。业务多样性带来的挑战是如何将多种业务共用一个资源池做混跑。

第二,大颗粒的工作越来越多,几年前支流视频是 480P,而当初的支流是 720P、1080P 的解决工作,将来能够预感 4K、8K、VR 这样的媒体解决会越来越越多,这带来挑战是对单机性能的渴求会越来越大。

第三,调度层须要预估每个工作的资源耗费,但单机工作的理论耗费会受到十分多因素的影响。视频内容的复杂度,不同算法参数,多过程的切换,都会影响工作资源耗费。

第四,编码的前解决会越来越多,同时一个转码工作须要做多码率或者多分辨的输入。各种前解决(画质加强 / ROI 辨认 / 超帧率 / 超分等)都会大幅减少的解决老本。

咱们看下从整体思路来看怎么去优化这三条曲线。

理论工作的资源耗费优化,次要办法是每个工作的性能优化、算法的性能优化、Pipeline 架构优化。

资源的调配外围指标就是使上图的黄色曲线可能一直地贴近彩色曲线,缩小资源分配的节约。当资源分配有余的状况下,能够做算法的主动升降级,免得线上工作呈现卡顿,比方编码器的 preset 从 medium 档升高为 fast 档。

对于总资源池优化,首先能够看到黄色曲线有波峰波谷,如果以后点播工作处在波谷的状态,能够把直播的工作调过来,这样能够在整个池子的峰值没有变动的状况下跑更多的工作。第二,总资源池怎么样可能疾速的弹性,在肯定工夫窗口内可能疾速开释掉资源,升高资源池耗费,这也是调度须要思考的老本优化的外围。

上面开展谈下一些优化办法。

CPU 指令减速

CPU 机型优化的次要指标是减少 CPU 单机的吞吐量,缩小 CPU 碎片。上图形容了多核 CPU 带来的劣势。但多核 CPU 也可能会带来多个 NUMA node 间接的内存拜访,从而导致性能降落。

单机资源准确画像

单机资源准确画像次要指标是可能准确晓得每个工作它须要多少资源,它是一个系统性的工具,须要有画质评估的工具、计算资源统计的工具、须要包含各种多场景简单的视频集、以及可能去做各种计算资源和迭代反馈,修改成本计算的耗费,领导算法的自适应升降级。

1-N 架构优化

一个转码工作可能要输入不同的分辨率和码率,传统的办法是起 N 个独立的一转一的过程。这样的架构不言而喻会有一些问题,比方冗余的解码计算和编码前解决。一个优化办法是把这些工作做整合,从 N 到 N 的转码变成一到 N 的转码。这样视频解码和编码前解决都只须要做一次,从而达到老本优化的指标。

1-N 转码也会带来新的挑战。FFmpeg 转码工具反对 1-N 转码,然而各模块是串行解决的,单个一转 N 工作的速度会比单个一转一的工作慢。第二,调度的挑战,单任务资源颗粒度会更大,所须要资源的调配也更难预计。第三,算法成果的差别,因为有的视频的前解决可能是在 Scale 之后,对于一到 N 的转码架构会把前解决放到 Scale 之前。媒体解决的流程变动会引起算法成果的差异(通常这个问题不是特地大,因为在 Scale 前解决没有画质损失,在 Scale 前做解决反而是更好的)。

端 + 云的协同媒体解决零碎

端侧媒体解决的劣势是可利用手机端现成的算力来降低成本,所以现实状况是充分利用各种端侧的算力,每个算法都做十分好的性能优化、端侧的适配,在每个端都能零老本的落地。

然而现实很美满,事实很骨感。会有四大事实问题:

第一,端侧适配的艰难。须要大量的 OS 硬件机型适配。

第二,算法接入的艰难。现实情况下不可能把所有的算法在所有端上都进行优化,所以端侧的性能瓶颈会导致算法落地艰难。

第三,体验优化的艰难。客户会有不同的 SDK ,或者说阿里云的 SDK 也会有不同的版本,SDK 自身存在碎片化导致一些计划难以落地。比方非标的 H264 编码,实际上 H265 编解码算法的落地也遇到挑战,一些设施并不反对 H265。

第四,用户接入的艰难,客户降级 SDK 或替换 SDK 的周期比拟漫长。

面对这样的事实,咱们提出云和端协同的媒体解决解决方案。次要思路是通过云上解决 + 端侧渲染的计划,达到比拟好的用户体验。

云和端的协同的媒体解决次要类型是转码类和预览类。转码类是单向的数据流。预览类须要把各种流先推到云端,再加各种特效,而后再拉回来给主播看成果是不是合乎他的预期,最初再从 CDN 推到观众端。

这样的计划也会碰到一些挑战。首先,云端解决会有计算成本的减少(当然能够有各种形式优化,因为客户端没有间接体感)。第二,延时会减少,云端的解决减少了链路的延时。

随着 RTC 技术越来越成熟,通过 RTC 低延时的传输协定,再加云端的各种老本优化,能够低成本 / 低延时地反对云上的媒体解决,打造一个云加端的实时媒体解决服务。阿里云视频云构建的 RTC 实时媒体解决服务 RMS,能够做到高性能、低成本、高画质、低延时、更智能的云端协同媒体解决的计划。

下面的左图是 RMS 整体架构图,分为 Pipeline 层、模块层、硬件适配层,硬件层。Pipeline 能够做各种业务场景的组装模块层,模块层是音视频解决的外围,实现各种 AI 或者是低延时高画质的成果。

端加云的协同媒体解决:赋能 RTC+

以剪辑云渲染为例,传统的剪辑计划要保障多端体验一致性及晦涩的性能是比拟艰难的。咱们的思路是端上只做指令的下发,视频的合成、渲染都是在云上实现,能够反对十分多的特效,也可能保障多端的成果一致性。

咱们看下剪辑云渲染的 Pipeline。云渲染的网页负责信令下发,通过调度层把剪辑指令转发到 RMS 媒体解决引擎做云上媒体解决的渲染,合成之后再编码通过 SFU 推流,最初在剪辑的网页端看剪辑成果。上图的 Demo 能够看到,网页把很多 Track 合成一个 Track ,4 乘 4 的宫格在端上解决的话,在低端机跑起来是比拟费劲的,但云可能轻易跑出这样的成果。

高码率低清晰度的视频流到云端后,通过阿里云视频云的云端窄带高清技术解决,能够达到更高清晰度更低码率的指标。下图 Demo 中启用窄带高清后,视频的清晰度有显著的晋升(码率也有显著降落)。

同时利用 RTC 低延时,再加 AI 特效的解决,能够产生很多有意思的场景。把真人的流推到云端,云端做卡通人像的输入解决,而后输入卡通人像做实时的交换,在会场的观众互相看到的是各自的卡通人像。

搭配云端的抠图技术很容易就能实现虚构的教育场景和虚构的会议室场景。比方虚构课堂,能够把人像抠到 PPT 里减少整个成果演示的沉迷感。虚构会议室里不同的参会者通过抠图把他们排列到虚构的会议室场景里来,达到虚构会议室的成果。

「视频云技术」你最值得关注的音视频技术公众号,每周推送来自阿里云一线的实际技术文章,在这里与音视频畛域一流工程师交换切磋。公众号后盾回复【技术】可退出阿里云视频云产品技术交换群,和业内大咖一起探讨音视频技术,获取更多行业最新信息。