全文 3514 字,预计浏览工夫 26 分钟
一、背景
在全民视频的时代,百度 APP 中视频播放是非常重要的业务。随着 5G 的到来,视频播放曾经不满足以前的标清 / 高清,超清乃至于 4K 曾经是旧时王谢堂前燕飞入寻常百姓家。越来越清晰的视频源,越来越简单的视频编码,对 APP 的视频解码能力也有越来越高的要求。
与此同时,大家的手机性能越来越好,很多手机都逐渐提供了强悍的硬件解码能力;而软件解码倒退多年,也有其不可代替的劣势。所以,如何正当利用手机的软 / 硬件解码能力,充分发挥其各自劣势,为用户们提供更加优质的视频播放体验,就成为了咱们重点优化的方向。
1.1 软 / 硬件解码优缺点
解码器有两种模式:软件解码与硬件解码。
软件解码目前业界有比拟成熟的 FFmpeg,利用 CPU 进行解码。
硬件解码倒退起步较晚,在 Android 手机上,利用专用解码芯片进行解码。零碎提供 MediaCodec,用于拜访底层硬件解码器。
事物都有两面性,两种解码模式各有优缺点,在很多播放器中,两种模式并存。软硬解码的优缺点,对音视频开发者其实算陈词滥调了。
阐明 :在 Android 上,MediaCodec 更加具体来说,是 Google 提供的一套框架,因为各个芯片厂商,手机厂商实现差别,所以经常出现兼容性问题。另外 MediaCodec 的初始化流程长,且一些手机上,须要外部缓存多个帧后才对外输入第一个帧,这两个因素导致硬解在首帧解码速度上显著比软解慢。
1.2 效率比照
1. 软件解码:应用 FFmpeg,解码后失去 YUV 数据,须要通过 libyuv 转换为 RGB,渲染上屏。
2. 硬解码 buffer 模式:应用 MediaCodec,解码后从 buffer 中失去 YUV 数据,须要通过 libyuv 转换为 RGB,渲染上屏。
3. 硬解码 surface 模式:应用 MediaCodec,官网阐明中 surface 模式为最高效的模式:解码时绑定 surface,解码后可通过零碎 API 间接上屏到 surface。
- 首帧解码耗时线上统计:
![图片](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/bb25d00473594350ac835836daead064~tplv-k3u1fbpfcp-zoom-1.image)
(百度 APP 版本 V11.20.0.14,数据日期:2020 年 03 月 20 日)
-
解码帧率和 CPU 占用统计须要进行压测(不进行音视频同步,齐全放开解码性能),以下这两项采纳线下测试数据。测试源:4K HEVC,测试机魅族 16th。
阐明:解码帧率越高,示意 1 秒内解码帧数越多,单帧解码耗时更少,性能更高。
CPU 如下图:
由此能够看出,在视频播放上,MediaCodec surface 模式是效率最高的模式,既充分利用了硬解码的劣势,又因为零碎间接上屏升高了数据拷贝和 YUV 转换 RGB 的耗时,无效升高了 CPU 负载和对内存的耗费。
1.3 痛点
综上所述,在视频播放中,现实状态是尽可能地去用硬解码 surface 模式,其次是应用硬解码 buffer 模式,最初再思考软解码。但同时须要兼顾首屏解码速度,硬解码的机型兼容性,在这些场景下须要优先应用软解码。
对此,咱们须要解决以下痛点:
1. 怎么欠缺硬解码的兼容性判断?
2. 怎么在保障首屏解码速度的状况下,尽可能应用硬件解码?
二、咱们的计划
痛点 1:怎么欠缺硬解码的兼容性判断?
- 支流做法:线下测试各种机型硬件解码兼容性,保护动态硬件解码黑名单。
- 劣势:测试人力老本高,且线下测试很难 cover 线上多种机型;手机型号一直迭代,这种形式,无奈保障新的异样机型及时拉黑。
- 咱们的计划 1:在动态硬件解码黑名单机制上,减少解码器监控。
痛点 2:怎么在保障首屏解码速度的状况下,尽可能应用硬件解码?
- 支流做法:须要保障解码效率的播放场景抉择硬件解码,须要保障首屏解码速度则抉择软件解码。
- 劣势:抉择软件解码的场景,无奈充分发挥手机硬件解码的劣势。
- 咱们的计划 2:
- 划定首屏解码耗时阈值,例如 200ms。
- 从解码器监控模块中获取历史硬解码首屏耗时进行预测,若低于阈值,间接应用 MediaCodec surface 模式;高于阈值,应用软解起播,中途无缝切换为 MediaCodec buffer 模式。
如上述,下文具体介绍这 2 个计划。
计划 1:解码器监控
1. 解码器监控模块设计
-
解码监控模块通过编码类型(H264/HEVC)& profile & level 作为一个 ID,记录各种编码方式源的软硬件解码状况;
阐明:profile 指定视频的压缩率;level 指定分辨率、帧率和码率的。两者都是视频编码的重要特色。同一编码类型,解码器对不同级别的 profile/level 反对可能不同。
- 记录该编码方式中软硬件解码的首屏解码速度和均匀解码速度。
- 针对硬件解码,还记录了硬件解码器是否存在解体;运行次数及运行期间出现异常的次数(包含解码接口抛异样;解码 block 等)。
- 刚装置百度 APP 的一段时间内,视频播放会随机应用软 / 硬件播放,用于采集该机器的解码器运行状况。
2. 流程
- 起播时,在 prepared 阶段,先通过动态硬解码黑名单,再细分到 编码类型 & profile & level,从解码监控模块看视频源编码方式硬解是否解体—> 硬解是否异样过多,判断硬解码兼容性是否满足。
- 从解码监控模块获取以后视频源编码方式应用软硬解码首帧耗时进行首屏耗时的预测,硬解码满足特定首屏耗时时,优先应用硬解码,反之则选软件解码起播。
- 视频播放后,将本次的首帧解码耗时、解码器运行状况(是否解体、是否有异样、每帧均匀耗时)更新到监控模块,用于下次播放预测。
对于硬件解码有解体、异样过多的状况,咱们断定硬件解码存在兼容性问题,用软件解码播放残缺个视频。
对于硬件解码首屏耗时超过阈值的,其实兼容性是 OK 的,那么在用软件解码疾速起播后,咱们能够用计划 2 进一步优化。
计划 2:软硬件解码器无缝切换
1. 解码通路的对立
为什么要对立?工欲善其事,必先利其器。
如果有一个对立的解码模块,封装软 / 硬解码器(包含三种解码形式),对外提供对立接入接口,那么对于 Player 依然像应用一个一般解码器一样应用。在整个架构实现上更加正当,保护扩大也不便。
模块外部保护前后台解码器,外部状态,切换追帧等逻辑,对外无感。而 I 帧标识,可切换标识等,均可携带在 pkt 中传入,这样也不须要对解码模块减少一些解码无关的接口,接口设计更加正当。
2. 解码器切换逻辑
两种机会能够切换:1)播放解码到第二个 GOP;2)Player 产生 seek。
播放到第二个 GOP 切换:
- 播放开始时,解码模块内关上软解码器作为前台解码器;同时创立后盾硬解线程,处于期待状态,并不会阻塞住前台解码工作。
- Player(播放器)开始播放,把第一个 GOP 的 pkt(视频包)给解码模块,利用前台解码器(软解)的劣势,疾速解码首个视频帧用于渲染显示,实现疾速起播。
- 4- 5 秒后,第二个 GOP 到来,pkt(视频包)携带可切换的 flag 告诉解码模块,同时输出 GOP2 的多个 pkt 给硬解码器在后盾解码,进入追帧状态。前台软解码器解码放弃不变,输出一个 pkt,解码一个帧。
- 当后盾硬解码器 PTS 追上软解码器的 PTS,即可敞开硬解码线程,前后台解码器切换。此过程需保障帧的间断,达到无缝切换,用户无感。
- GOP2 的后续的 pkt 和后续的 GOP3/4/5……都会应用 MediaCodec buffer 模式。这样在利用软解保障首帧解码速度的同时,也最大限度的利用了 MediaCodec 的解码劣势。
Player 产生 seek 切换:
这种场景逻辑比较简单,在 Player seek 时,须要调用 decoder 的 flush,咱们趁此机会把前台解码器切换为硬解码器,后续始终用 MediaCodec buffer 模式即可。
3. 保障解码器无缝切换
追帧和解码器切换过程中有两种状况:
- (左图)GOP2 硬解码解码 N 帧后,才追上软解码,那么这些反复的 frame(灰色局部),须要进行抛弃,防止画面反复和回跳。
- (右图)GOP2 硬解码解码第一帧,即曾经追上软解码,那么必须填入空 pkt 包,将软解码器外部缓存全副输入,防止画面跳变。
三、结语
目前百度 APP Android 端,在保障首屏速度和解码错误率没有进化的前提下,视频播放中硬件解码占比已达到 87%,如下:
在目前视频业务百花齐放的时代,编解码也在一直倒退提高,各种新的编码方式层出不穷,端上也在这个方向上一直强化本身解码能力。解码作为视频播放中重要的一环,能够预感的是,后续咱们仍会在端上解码一直进行摸索、优化,为用户提供更优的体验。
举荐浏览 :
百度爱番番实时 CDP 建设实际
当技术重构遇上 DDD,如何实现业务、技术双赢?
接口文档主动更改?百度程序员开发效率 MAX 的秘诀
技术揭秘!百度搜寻中台低代码的摸索与实际
百度智能云实战——动态文件 CDN 减速
化繁为简 – 百度智能小程序主数据架构实战总结
百度搜寻中台海量数据管理的云原生和智能化实际
———- END ———-
百度 Geek 说
百度官网技术公众号上线啦!
技术干货 · 行业资讯 · 线上沙龙 · 行业大会
招聘信息 · 内推信息 · 技术书籍 · 百度周边