当前位置: 首页 > 后端技术 > Java

网易云信NERTCH.265高清画质体验工程实践-经验分享技术专题

时间:2023-04-01 21:11:13 Java

介绍:H.265是ITU-TVCEG继H.264之后制定的新一代视频编码标准。与H.264相比,H.265可以进一步提高压缩效率,提高图像质量。在目前的很多音视频场景中,已经得到越来越广泛的应用。我们在网易云信NERTC实践中做过很多H.265的项目,本文是经验分享系列的第三篇-视频篇,文章将从四个方面进行具体介绍。能力协商客户端能否发送指定特性的码流,不仅取决于本端是否支持编码,还取决于房间内的其他接收端是否可以解码。即发送端和接收端共同决定该端可以发送什么样的码流。对于H.265,可能会出现以下情况:那么他们之间将如何通信呢?如果clientB发送H.265码流,由于clientA和clientD只支持H.264解码,无法对clientB发送的H.265码流进行解码,所以需要设计一套能力协商机制来保证正常通信支持不同编解码器功能的客户端之间。下图是能力协商的总体设计:下面详细介绍我们的能力协商设计方案。能力集设计能力集定义为{uint32key:[uint8value1,uint8value2...]},使用1-bitmasksdkkeyrangeis[0,2^8)thevideokeyrangeis[2^8,2^16)audiokey的取值范围为[2^16,2^24)字节如下所示:示例如下:能力协商过程(客户端)客户端定义能力集locally客户端在本地实现能力集上报,能力集下发配置机制server端提供通道内能力集的生成、合成和下发。示例:定义:capability字段VideoCodec:256(2^8),capability值H.264:0,H.265:1当clientA和clientB进入同一个频道时,clientA上报capabilityset{256:[0,1]},客户端B报告能力{256:[0]}。上报终端B的能力集后,知道A支持H.264和H.265,B支持H.264,综合A和B的能力集,得出信道支持H.264的结论获取到能力集{256:[0]},客户端A收到能力集后,主动关闭自己的H.265能力;客户端B收到能力集后,认同自己的能力集,不做改变。能力协商过程(服务器端)创建房间时,会生成一个默认的能力集。**默认的能力集由引擎提供,服务器作为全局配置。**如果第一个edge_login请求有能力集字段,使用这个能力集覆盖默认的能力集,作为能力集房间的;如果没有能力集字段,则使用默认能力集作为房间的能力集。由于是第一个,所以不需要广播。每个用户进来后,如果能力集大于房间的能力集,则将房间的能力集返回给用户,房间的能力集不变。示例如下图所示:每个后续用户进来,如果能力集小于房间的能力集,则取交集,缩小房间的能力集,将结果广播给所有用户。举例如下图:H.265编解码实践每个平台都有自己独特的硬件265编解码,也有各种开源软件265编解码,那么我们如何选择才能达到最好的使用效果呢?下面我们分别针对Android、iOS、Mac和Windows四种平台分别介绍265编解码器在各个平台上的做法。其中,软件编码器使用x265进行评估,软解使用ffmpeg和libhevc进行评估。安卓端,先看看安卓端硬件编解码的功耗和码率(测试机型小米10:QualcommTechnologies,IncSM8250,测试Profile:720P30fps1.7M)再看软件编解码android端(测试机型小米10:QualcommTechnologies,IncSM8250,测试Profile:720P30fps1.7M)最后看画质对比(测试机型小米10:QualcommTechnologies,IncSM8250,测试Profile:720P30fps858k),左边是H.264,右边是H.265。总结:android硬编码265的功耗与硬编码264基本一致,同时android硬编码265的码率比硬编码264更稳定。性能android端软编码的265还是比较差的,不能满足需求。android端的ffmpeg软解265在arm64上性能比较差,CPU占用率高达15%。同样条件下,使用libhevc,CPU占用率仅为4.5%,性能提升空间很大。硬编码265的画质明显比硬编码264清晰,画质优势明显。因此,我们265编解码在android端的使用策略是:优先使用265硬编。部分设备有265硬解码兼容问题,高端机型选择265软解码,低端设备直接认为不支持265解码,首选265硬编码。如果部分设备存在265硬编码兼容问题,则认为不支持265编码,降级为264编码。因为libhevc软解码的性能明显优于ffmpeg软解码265,所以我们会优先考虑libhevciOS端进行265软解码。再来看看iOS端硬件编解码的功耗(测试机型iPhone11,测试Profile:720P30fps1.7M)另外,我们发现在部分机型或者某些场景下,iOS硬编码265会有一个明显的码率不足问题(测试机型iPhoneXR,测试profile:720P30fps1.7M)H.264:H.265:针对这种码率严重不足的情况,我们硬设计了一套基于iOS的码率监控-codedcontrol方式,如果监控码率严重不足,会从H.265回落到H.264最后看硬编码码率稳定情况下的画质对比(测试机型iPhone11,testProfile:720P30fps858k)左边是H.264,右边是H.265总结:硬编码265使用iOS功耗明显大于硬编码264,265使用iOS功耗iOS硬编码也明显大于硬编码264。iOS硬编码265偶尔会出现一些码率不足的情况,画质不如2643。iOS硬编码的画质265比硬编码的264更清晰,并且有一定的画质优势。所以最后,我们在iOS端使用265编解码的策略如下:1.优先使用硬编码265,不支持软编码2652。优先使用硬解码265,只回退到ffmpeg265软解码硬解码265多次恢复失败是由于iOS265硬件编码功耗比硬件264大,监控iOS设备整体功耗。在低功耗情况下(比如20%临界点),我们将硬件265切换回264硬件编码器,使用iOS硬编码控制模块监控实际编码率,如果码率明显不足或者码率过高,我们将硬编码265切换回硬编码264iOS硬编码控制TargetBitrate传给码控模块。HWBitrateController在每次编码完成后将编码后的帧大小更新到HWBitrateController中,以估计每秒的实际编码码率。估计比特率计算目标比特率和实际比特率之间的直接差异。Diff采用二分法,取0.5倍Diff加上TargetBitrate,作为要调整的码率,AdjustedBitrate,将要调整的码率设置回hardcoderHWEncoder,作为HWEncoder的目标码率,TargetBitrate,然后回到第一步,hardcoder转换当前目标码率TargetBitrate被传递给码控模块HWBitrateController计算Diff/TargetBitrate。如果持续大于30%,则认为码率明显不足,需要触发Mac端编码器降级。首先我们来看一下Mac端265软硬件编解码的CPU。和比特率(测试型号MacBookPro(15英寸,2016):Intel(R)Core(TM)i7-6700HQCPU@2.60GHz,测试配置文件:720P30fps1.7M)硬编码265比特率:软编码265位rate:同时,我们通过转储Mac对265比特流进行硬编码,发现使用了前向B帧,而不是P帧。最后来看画质对比(测试机型MacBookPro(15英寸,2016):Intel(R)Core(TM)i7-6700HQCPU@2.60GHz,测试配置文件:720P30fps1M)总结:与软件对比265,硬件265在Mac上CPU占用率更低,性能提升更明显。2、硬编码265码率稳定性不如软码265,波动比较大,但围绕目标码率波动。经过长时间的测试,发现整体码率平均没有明显的超调或不足。3、硬编码码流之前的B帧换成P帧,整体压缩率会更高,同样码率下画质会更好。我们265编解码器的使用策略是:先用265硬解。部分设备存在265硬解兼容问题或不支持265硬解。在CPU性能强的设备上使用软解265(ffmpeg)。如果是CPU较弱的设备,则认为不支持265解码,首选265硬编码。部分设备存在265硬编码兼容问题或不支持265硬编码。在CPU性能强的设备上使用软编码265。如果是CPU较弱的设备,则认为Windows不支持265编码。硬解的碎裂比较严重。我们暂时没有考虑使用硬编码和硬编码的方案。目前,我们主要使用软编码和软编码解决方案。下图是win上软编软解265的情况(测试机型DellLatitude5290:Intel(R)Core(TM)i5-8250UCPU@1.60GHz,testProfile:720P30fps1.7M)可以看到:1.x86上软编码265和软解码265的性能不如x86_642。软编码265在x86_64上的CPU消耗也比软编码264高很多,所以我们265编解码在Win端的最终使用策略如下:1.在winx86的情况下,265软编和不直接支持软解码。2、winx86_64情况下,在CPU性能比较强的设备上开启265软编辑和软解码;同时,软编265对CPU性能的要求也高于软编。265解决方案更高,因此对设备的性能要求会更严格。在软解的时候,由于涉及到大量的编解码操作,所以还要考虑设备的性能。为了在整体工程层面提供最佳的用户体验,我们采用了白名单策略。通过白名单配置分发,可以区分支持265硬编码和硬编码解决方案的设备和支持软编码和软编码的设备。下面是我们的具体做法:通过大量的设备适配,将支持265硬编码和硬解码的设备配置到在线白名单中,通过设备跑分来区分设备的CPU性能,配置高性能设备支持265软编码和软解,低性能设备不支持265软编码和软解,然后更新配置到在线白名单,最后通过在线白名单配置发送,客户端获取当前是否支持硬编码H.265能力协商解决方案的配置信息和是否支持软编码和软解协商是关于H.265解码能力,协商结果最终应用于编码端。以及当前设备支持能力,三者综合获取当前H.265解码能力能力协商模块,根据当前H.265解码能力生成能力集,向能力协商服务器上报各客户端的能力在能力协商服务器的综合通道集合中,生成新的房间能力集,发送给各个客户端。客户端接收服务端的能力集,解析出当前频道的H.265能力集。根据当前频道设置的H.265能力、H.265编码配置下发、用户设置、当前设备支持能力、服务器对H.265的支持能力,三部分综合判断当前是否为H.265编码supported,最后作用于编码端是否编码H.265StreamingCPUOverUseStrategy通过跑分来区分不同设备的CPU性能可能并不完全准确。在实际场景中,可能会出现跑分数据高但编码性能不足的情况。这时候我们就需要实时监控统计当前的视频编码耗时,判断当前的CPU是否过载。我们的做法是:硬编码265。考虑到可能的流水线延迟,我们目前不统计每帧编码的耗时。在使用软编码265时,我们会统计每一帧的编码耗时。如果连续编码时间过长,会认为当前CPU过载,265软编会立即回落到264QP阈值调整我们的QOE模块会根据QP阈值调整帧率和分辨率,以达到最佳的主观视频质量,所以设置合理的编码器QP阈值非常重要,那么在实际工程实践中,我们如何为硬件265编码器找到一个合理的QP上下限阈值呢?我们的方法是:保证H.264和H.265的主观画质基本对齐,打印出QP值,生成QP曲线,根据QP曲线。我们以这个模型为例。示例:(测试机型小米10:QualcommTechnologies,IncSM8250,测试Profile:720P30fps)可以看出:在720p30fps的profile档位中,硬编码265和硬编码264质量基本一致,硬件265码率可以节省40%,QP波动基本差不多,上下阈值也基本接近。所以如果当前android硬编码264QP上下阈值为[A,B],那么建议android硬编码265QP上限阈值范围为[A-1,A+1],QP下限阈值范围为[B-1,B+1]根据步骤1得到的QP的上下限阈值范围,逐步释放网络损失,根据QOE模块的分辨率和帧率进行调整观察QP阈值,从QP阈值范围Threshold中找出最合理的QP,以如下数据为例:我们发现当QP阈值为[A-1,B-1]时,整体QOE性能是最好的,所以第一阶段选择[A-1,B-1]作为最终硬编码265的QP阈值收益评估,我们是基于与H.264分辨率码率的对齐,看画质收益、端到端延迟、CPU占用率、流畅度四大指标。这里我们先列出Android硬编码265和iOS硬编码265对比硬编码264的画质优势。从我们的评测来看,端到端延迟、CPU占用率、流畅度这三个指标基本不同.不多,但是画质的提升可以参考下面的图表数据:总体来说:265相比264,在视频画质上有明显的提升。画质收益会更明显3.android硬编码265的画质收益明显优于iOS硬编码265总结无论是硬编码265还是软编码265,与264相比,视频质量有明显的好处;未来,网易云信将进一步探索画质对齐和码率节省的维度。作者简介史凌凯,网易云信音视频引擎开发工程师,负责NERTC视频引擎的开发和维护。