乐趣区

关于移动端:优酷移动端弹幕穿人架构设计与工程实战总结

弹幕穿人计划次要分为两类:“云端离线人体宰割 + 端侧渲染”和“挪动端端侧实时人体宰割 + 端侧渲染”。在这里咱们别离简称为云端计划和端侧计划。
本系列文章次要聚焦在优酷端侧弹幕穿人的技术实战上,次要包含优酷跨平台多媒体渲染引擎 OPR 简介、优酷端侧弹幕穿人架构设计与工程实战、淘系端智能 PixelAI 挪动端实时人像宰割技术、以及优酷弹幕渲染及弹幕穿人渲染技术的方方面面。

一、背景

1、弹幕穿人的价值
弹幕是目前用户观影的一个标配,弹幕能使用户在观影过程中与其余用户实时互动,晋升了观影体验。但弹幕也会遮挡视频画面,也会给用户带来一些困扰。弹幕穿人是视频内容与弹幕内容抢夺用户视觉焦点的一种均衡,可能让用户在生产弹幕的同时,仍然能够观看到视频中波及人物等的要害画面区域。在有弹幕穿人成果的时候,用户有更强的志愿关上更多行弹幕,弹幕穿人对用户弹幕开启行数有肯定促进作用,从而证实弹幕穿人能产生正向的价值。
2、端侧弹幕穿人的劣势
相较于云端计划须要提前针对某个剧生产、部署、下发,在介质有变动时须要从新生产等等不利因素,以及动则上百万的生产、贮存及带宽老本,不适用于直播等实时场景。端侧弹幕穿人则齐全依赖于挪动端本身的算力,最大劣势是实时、低成本,并且利于大规模铺量。
3、端侧弹幕穿人的技术要求及难点
3.1)穿人成果要精确
无论是云端还是端侧,穿人成果都要求精确。否则如果不达标,mask 与人物有错位、弹幕渲染频繁抖动等等景象,这些都是不可承受的。
3.2)性能要达标
咱们要在端侧保障弹幕穿人成果和性能,不能因为端侧弹幕穿人而导致 CPU/GPU/ 内存等资源占用的飙升,或者导致弹幕自身渲染卡顿,更不能影响到视频或音频渲染的成果和性能。否则就是轻重倒置了。
相较于云端计划,端侧计划的挑战更大,次要体现在如下几个方面:
(1)算力无限
端侧计划只能利用挪动端本身的 CPU 或 GPU 来实现链路上所有操作。相较于云端计划,端侧的算力十分无限。挪动端、边缘端和云端的 GPU 算力的介绍能够参考这篇文章《GPU 深度报告,三大巨头,十四个国内玩家一文看懂》。
(2)模型小
因为端侧的限度,咱们不可能用大模型,这给检测的准确性也带来更大的挑战。
(3)实时性
弹幕穿人须要跟视频画面实时匹配。因为视频帧率个别在 25~60 之间,为了达到好的穿人成果,咱们对整个端侧弹幕穿人链路的实时性要求是十分高的。端侧穿人链路上所有操作,包含视频画面获取、人像宰割检测、弹幕穿人成果的实现及渲染上屏,所有这些操作加起来要求在 20ms 以内工夫实现 (超过 20ms 就根本能感知到弹幕的卡顿了),这样能力达到一个好的成果。否则穿人成果就会有滞后感、穿人成果与画面不匹配,甚至会对弹幕自身渲染的晦涩度和视频渲染的晦涩度都产生重大影响。
以上这些因素都会给端侧弹幕穿人我的项目带来微小的挑战。

在淘系算法同学的大力支持下,PixelAI 很好地实现了挪动端实时人像宰割的工作,给优酷端侧弹幕穿人性能的上线铺量打下了松软的根底。另外,咱们在工程侧也做了大量的优化(优化伎俩前面会有介绍),使市面上机型的大规模笼罩成为了事实。

二、整体架构设计

1、架构图
OPR(OPen Render 的缩写) 作为优酷主客全端的渲染引擎,次要负责 audio、video 和弹幕的渲染。另外,咱们也在 OPR 中引入了端智能引擎。因为 OPR 天生离 audio、video 和弹幕的 raw 数据最近,咱们能够间接在 OPR 里就去生产这些数据,产生咱们所需的端智能后果,给业务带来更大的价值。咱们不须要把数据再一层层地回传给更高的档次去做解决去做生产解决。所以咱们在 OPR 里融入一层端智能层,间接拿数据就能够解决端侧智能相干操作,而后把后果在 OPR 层展现、上报或者传给下层去生产,这样做的效率是最高的!

咱们首先看一下整个 OPR 的架构图:

OPR 从上到下分为 4 个档次:
(1)接入层
OPR 是跨平台的,咱们反对 Android(Android 手机和 OTT 设施)、iOS(iPhone、iPad、Mac) 和 Windows(DX9、DX11、DX12)平台。咱们形象出对应平台的接口,供业务层调用,来实现相应数据元素的渲染。
(2)引擎层
引擎层,按性能分为 Video Engine,Audio Engine 和 Danmaku Engine,别离对应 video、audio 和弹幕的引擎。
(3.1)渲染层
除了根本的 Video、Audio 和弹幕渲染性能之外,OPR 也包含相应的后处理能力,比方视频的帧享相干后处理、特效广告、色盲、zoom 等等能力,音频的倍速、均衡器等能力,弹幕的节奏弹幕、流光弹幕、心动弹幕等特效能力。
(3.2)端智能层
次要包含人脸相干能力、语音能力、超分能力等,上层是其对应的撑持库。
(4)平台层
对各平台渲染接口的封装,包含 2d/3d 的 opengl es、metal、directx 和 audio 的 opensl、audioqueue、directsound 等。
2、流程图

端侧弹幕穿人流程如下:

(1)video 失常解码、渲染流程中,咱们去实时截取以后视频画面帧;
(2)送给端智能模块,去做人像宰割,失去人体宰割 mask 数据;
(3)mask 作为单通道纹理上传至 GPU;
(4)mask 数据上传至 GPU 之后,咱们做一次 5 ×5 的 gaussian blur,这样边缘处边缘处更加平滑;
(5)把 blur 解决之后的纹理作为 alpha 去跟弹幕纹理做 blend;
(6)有穿透成果的弹幕 surface 叠加在视频 surface 之后,就能失去如上丝滑的弹幕穿人成果了。

三、工程实战

1、技术选型及实际
人像宰割能力,内部开源的 opencv 和团体内的 mnn 都有这个能力。然而咱们在挪动端实测之后得的论断是,性能和成果都达不到咱们端侧弹幕穿人的要求。起初咱们理解到,团体外部曾经有一个弱小的端上引擎 PixelAI,有弱小的人脸等解决能力,曾经在淘宝直播等场景上线。咱们疾速实测了一下,确实在成果和性能都能满足咱们的需要。所以咱们最终定型 PixelAI 来作为咱们端智能的主引擎来针对端侧弹幕穿人来实时做人体宰割。
2、性能优化
1.1)帧画面高效获取
(1)失常 video 渲染流程如下:

video 失常上屏流程是这样的,video 解码后的数据(硬解或软解),通过 aliplayer 调到 opr 的接口。video_player->video_engine->video_layer->video_pipeline,前面对接一个个后处理 filters 去实现各个后处理性能,最初上屏。
(2)用户截图场景下,帧画面的获取流程如下:

针对用户截图场景,因为截图场景不须要上屏,所以咱们自然而然想到如下流程,在所有的 filter 之后加一个 snapshot 的 filter,这个 filter 实现数据渲染到一个纹理,而后拷贝进去即可。
针对用户截图这种场景,上述流程没问题任何问题。咱们在加上 snapshot filter 之后从新走一遍渲染流程,截图实现后卸载 snapshot filter,整个流程耗时若干毫秒。针对用户被动截图这个场景,咱们不会因为这若干毫秒感知到性能存在问题问题。然而,当咱们把整个链路利用到端侧弹幕穿人这个场景下,咱们发现每一帧截图的这个若干毫秒的工夫,就是一个致命的性能问题了。如果不压缩工夫的话,留给算法的解决工夫就太少了,无奈达到上线的规范。

(3)端侧弹幕穿人场景,帧画面获取流程如下

针对这种须要频繁实时截帧的场景,咱们设计了如上链路。
咱们在所有 filter 的末端减少一路 quick_snapshot filter,这个 filter 有两路渲染 command。一路 command 按失常流程去渲染、失常上屏,不做任何额定解决。同时,另一路 command 把数据渲染到纹理,而后再拷贝进去。这样,两路相当于并行起来。在每一帧渲染过程中,不会有任何多余的创立和销毁 snapshot filter 的过程,齐全不会对失常渲染链路造成任何影响。同时,新加的一路 command 使截帧的效率最大化,很好地实时实现了频繁截帧的工作。
通过实测,咱们的截帧性能晋升若干倍,为算法去做实时人体宰割节俭了大量的工夫。
1.2)防止在 cpu 中实现耗时操作
PixelAI 有大模型和小模型,为了使底层的 MNN 不做频繁的初始化操作,大小模型要求的帧数据尺寸是固定的。如果大于或小于算法要求的尺寸,PixelAI 会先应用 OpenCV 去做 scale。理解到这些 scale 操作全副在 CPU 中实现,会造成大量的耗时,所以咱们针对大小模型,间接在后面的截帧操作中,通过纹理大小的变动,咱们就能够在 GPU 里实现了帧画面的 scale,使截帧输入的尺寸就是 PixelAI 大小模型所要求的尺寸。这样就防止了应用 OpenCV 在 CPU 中做 scale 锁耗费的大量工夫了。
1.3)异步调用模型
从算法同学理解到,PixelAI 人像宰割过程是一个原子操作,对应的底层 MNN tensor 等运算不可中端。一般来说,在 GPU 和高端手机的挪动端运算比拟快,但也有那种耗时比拟久的场景。算法侧咱们保障在一个固定的工夫内返回后果。
如果算法耗时较久不返回数据,咱们在这里死等的话,就会导致弹幕渲染卡顿、穿人成果的错位等异样 case,这是不可承受的。为了达到最好的性能和成果,咱们必须要实现一个异步调用模型。在失常工夫内返回后果的,间接应用 mask 数据上屏。在失常工夫没有返回的,咱们抛弃掉以后帧的 mask 数据。如果是若干帧以内没有返回,咱们都应用上一次检测的数据;为了防止这种场景下穿人成果的错位,超过若干帧就间接上屏,没有穿人成果了。这也是在工程上对弹幕穿人渲染成果做出的一个平衡解决了。
3、成果优化
要做到好的穿人成果,咱们在渲染层面也做了大量的优化,参见文章《优酷弹幕穿人渲染技术揭秘》。
4、测试论断
(1) 算法测试后果,参见文章《PixelAI 挪动端实时人像宰割》
(2)优酷整体测试后果
测试论断:咱们并没有因为引入端侧弹幕穿人带来大量的性能损耗。

四、瞻望

挪动端端智能是将来一个趋势,挪动端弹幕穿人是端智能一个很好的利用场景。后续咱们会在 OPR 里衍生出更多的端智能利用场景,给优酷用户的观影带来更好的用户体验。

更多娱乐相干技术解读,移步➡️【阿里巴巴娱乐技术 公众号】

退出移动版