当前位置: 首页 > news >正文

快手高性能移动端多媒体引擎架构

当前,越来越多的用户选择使用手机进行视频创作,随着视频UGC时代的到来,用户不再满足于简单地视频拍摄,更希望一些专业的剪辑功能在移动端实现。在计算性能非常有限的情况,要实现这些高负载的功能,面临着非常多技术的挑战。本文来自于陈彬在LiveVideoStackCon2019北京站上的精彩分享。

 

文 / 陈彬

整理 / LiveVideoStack

 

大家好,我是陈彬,目前在快手负责短视频架构工作,主要负责构建快手的移动端多媒体引擎,提供短视频拍摄、编辑、发布等视频创作的基础能力,还有消费侧的播放器SDK和短视频后端转码服务。在加入快手之前,从事过很多视频技术相关的领域,如视频编解码算法、传输算法、多媒体芯片、OTT设备等。

今天,我演讲的主题是“快手移动端高性能多媒体引擎”,将重点围绕高性能这一话题来展开,从宏观到微观,介绍引擎的整体架构和具体场景的优化手段。演讲分为快手多媒体引擎概况、高效使用硬件资源、拍摄和编辑场景的性能优化三个部分,最后一起展望一下5G+边缘计算在短视频方面的应用。

1.  快手多媒体引擎概况

1.1 UGC平台

众所周知,快手是一个短视频UGC平台,而视频内容的生产是内容供给的源头,用户通过使用手机的拍摄和编辑功能创作视频,然后上传到快手平台。之后,后端服务器利用AI技术对这些视频进行内容理解,把理解的信息传送给推荐引擎,推荐引擎结合用户兴趣,进行个性化推荐,进行分发消费。消费用户通过观看、点赞、评论和私信等动作产生一系列的互动行为,这些互动行为同时又进一步促进了内容的生产。

这是一个正向反馈的链路,社区像滚雪球一样不停的增长。这就是快手最重要的UGC生态闭环。

快手目前DAU超过2亿,作者数1.9亿,每天新增作品数1500万,生产者的比例也很高,用户分布非常广,手机型号有几千款,价格区间从几百元到几千元。这些生产者使用快手移动端的多媒体引擎来进行创作,通过AI技术赋能内容生产,为用户提供生产创意,降低生产门槛,从而提升作品的数量和质量。

 

1.2 AI赋能内容生产

AI技术落地是非常困难的,快手想要实现AI落地,首先要做好基础平台、算法和产品这三个要素。基础平台是指移动端多媒体平台,包括快手自研的深度学习推理引擎YCNN、3D渲染引擎和多媒体引擎。复杂的AI算法运行在这三个高性能的引擎上,例如人体理解、场景理解、语音识别、图像增强等算法,这些算法的效果通过产品形态呈现给用户。

举例说明这些AI算法的落地场景。第一个是“萌面”魔法表情,用户在拍摄视频的时候。无需3D结构光摄像头也可以实时捕捉面部表情,并实时把面部表情通过卡通头像的形式展现,能够实现非常丰富的面部表情。第二个是梵高的天空特效,使用了天空识别算法。第三个是前段时间特别受欢迎的娃娃脸,通过GAN技术把用户的脸秒变童颜,可以在安卓和iOS大部分的机型上实时运行,技术挑战非常大,快手也是国内首家实现这项技术的公司。第四个是自动添加字幕功能,通过识别算法,将语音转换为文字。最后一个是暗光增强算法,通过该算法可以对暗光环境下拍摄的视频进行提亮和去噪,还原更多的细节。

这些都是AI赋能内容生产的实际应用,通过平台、算法和产品三要素,实现了原创、好玩、清晰和流畅,这是快手平台上每天能产生海量作品的秘密之一。

 

1.3 快手短视频生产消费整体链路

上图是我们整个生产到消费的链路,由作者端、云端和观众端三部分组成。作者端也就是生产侧,通过拍摄、导入、编辑等操作生产视频,然后把视频发送到云端,云端对视频进行存储和转码,分发给CDN,最终通过CDN网络传输给用户进行消费。本次演讲内容的重点是位于作者侧的移动端多媒体引擎。

 

1.4 快影

在快手主app之外,我们还孵化了一些独立的内容生产App。说到视频制作方面,就必须介绍视频剪辑工具——快影,它主要面向更专业一些,需要在移动端进行较复杂视频编辑的用户。

快影最近霸占了App Store免费排行榜榜首的位置。它的功能更加专业,支持超高清视频的编辑和AI特效功能,是快手移动端多媒体引擎赋能的一个代表性产品,我下面将会用快影的案例进行分析。

 

1.4.1 多媒体引擎是什么

简单来说,多媒体引擎主要负责视频的采集和后期处理,其功能分为拍摄和编辑。拍摄包括滤镜、美颜美妆、AI特效等功能,编辑包括了剪辑、转场和贴纸等功能。

这些功能的背后面临着4K分辨率、3D渲染、美颜美妆、端上AI等技术挑战。这些挑战都需要庞大的计算量,再加上实时处理的需求,可谓是难上加难。要解决这些问题,首先就必须要高效的使用硬件资源。

 

2. 高效利用硬件资源

2.1 并行化基本原则

手机端的硬件资源主要有CPU、GPU、HW Codec等模块,使用这些资源最简单的办法是轮流使用,但这种方法并不高效,例如,会出现CPU工作,但是GPU空闲的情况。因此要做到并行化,让所有硬件同时工作,这是一个非常基本的原则,也是快手多媒体引擎架构设计的一个指导思想。

 

3. 拍摄和编辑场景的性能优化

 

3.1 拍摄场景

理清设计的指导思想后,再看一下具体的优化场景。对于拍摄,从相机采集的一帧视频数据先后要经过图像算法、滤镜、美颜美妆、魔法特效等模块,然后分成两路,一路给实时预览,一路给录制,整个流程要在33毫秒之内完成(30fps)。

 

3.2 拍摄的架构

拍摄的架构需要支撑起实时采集、实时处理、实时预览和实时录制的应用场景。整个架构从下往上分成三层。

最下面一层是采集和渲染的Pipeline流水线,由采集模块、CPU处理单元、GPU处理单元、显示模块和录制模块组成。

中间一层由各个算法模块和特效渲染模块组成,是以plugin的形式插入到底层渲染流水框架中,类似ffmpeg的filter,通过排列组合,实现各种效果。这些filter之间是有依赖关系的,由一个负责依赖管理的模块DependencyManager进行控制。在此之上是非常重要的monitor模块,它对整个流水线进行实时监控,包括算法模块耗时、CPU负载、GPU负载、内存使用量、帧率以及分辨率等方面。

这些数据实时采集后发送到快手后端的流媒体大数据平台,进行实时清洗、聚合和展示。基于这些数据,可以实时监控生产模块的性能。整个过程是分钟级别的延迟,也就是说,拿出快手APP进行拍摄,一分钟之后就能在后台看到整个操作流程的性能数据。根据这些性能数据,对架构进行针对性的优化。这也是快手一直以来实践的方法,以大数据为驱动来进行性能优化,提升用户体验。

中间层之上是APP接口层,在安卓和iOS平台上分别提供了Java和OC的接口。整个架构作为一个跨平台的方案,除了最上层的APP接口层,大部分使用C++来实现。

前面提到的高效使用硬件资源的思想体现在框架图中最底层的链路上,从相机采集的数据先传递给CPU处理模块,CPU处理完之后把数据传给GPU,然后CPU立刻再去相机采集下一帧的数据。在同一时间点,CPU正在处理当前刚采集的一帧数据,而GPU正在处理前一帧的数据,CPU和GPU是并行工作的,这就是高效利用硬件思想的一个很好的体现。

框架图中的YCNN引擎是快手Y-TechAI实验室开发的移动端的推理引擎,各类AI算法都运行在YCNN上。例如,最常用的人脸关键点算法,人体关键点算法和手势关键点算法。YCNN引擎通过Metal、OpenCL、SIMD这些加速方式,充分利用底层的CPU、GPU和NPU资源。除了高效使用这些硬件资源之外,还做了4个方面的优化,第一点是算子融合,把算子打包在一起,load进CPU的cache,这样可以减少分别load的额外消耗。第二点是内存优化,尽量避免频繁地内存读写操作,尽量一次读完数据,处理完后一次性写入,避免对同一段数据反复读写,同时要注意做内存排布优化,增加cache命中率。另外两点是通用的磁盘I/O优化和多线程优化。

经过这些优化后,在iPhone6手机上实测,人脸关键点处理速度是200fps,一秒能处理200帧图像,人体关键点是90fps,人体分割是100fps,都是业界非常优秀的性能。

 

3.3 分辨率和帧率的变化

除去技术侧性能的指标,快手也很注重从用户主观感受出发,衡量优化对用户体验的收益。快手制定了拍摄场景的三个关键指标:分辨率、帧率和卡顿率。分辨率和帧率很好理解,而卡顿率一般出现在视频播放场景。先看分辨率和帧率的变化,随着多媒体引擎的上线以及持续性能优化,快手的拍摄分辨率从之前540P升级到720P,部分机型已经升级到1080P,帧率也在持续的上升,实现了更清晰和更流畅。

 

3.4 卡顿率

但是,我们发现,仅靠平均帧率并不能全面反映一个视频的流畅度。以一个实际例子来看,我们一位同事去澳洲旅游,在当地拍摄的这段视频里,出现袋鼠的画面特别卡顿,但是,整个视频的平均帧率其实已经达到20fps以上。正常情况下,20fps+是比较流畅的,而这个视频却看起来很卡,什么原因呢?

我们仔细看了一下帧率的分布,发现帧率分布非常不均匀,因此发现之前评估视频是否流畅仅靠平均帧率是有缺陷的。为了解决这个问题,快手定义了拍摄卡顿率指标。相邻两帧时间戳之间的差值大于200毫秒就认定为卡顿,卡顿率是指发生过卡顿的次数除以总的拍摄次数。卡顿率结合平均帧率才能更全面地去衡量拍摄视频的流畅度。

 

3.5 卡顿率的变化

从上图的卡顿率的曲线可以看到,经过优化后,卡顿率在持续下降。通过分辨率、帧率和卡顿率这三个指标,可以看到,经过持续的优化,用户感知是更加清晰、流畅。

 

3.6 编辑场景

在编辑场景方面,上图两个页面是快影的主要页面,其中展示了快影的部分编辑功能。左边页面包括了添加视频片段、分割、倒放和旋转等操作,右边页面是添加转场的操作。

相比于iOS,安卓端的技术挑战更大。安卓硬件解码是一个老生常谈的问题,相比于软件解码器,硬件解码器更快,特别是在高分辨率视频场景下,优势更加明显。

 

3.7 安卓硬解码

上图是导入一个4K视频进行编辑的场景,左边是市面上一款很火的编辑工具,从预览页面点击“下一步”到编辑页时,有一个“合成中”的等待,之后才能进入编辑页。需要等待的原因是视频的分辨率太高,如果不使用硬件解码器,很难在编辑页面做到实时操作,因此需要提前做一次转码,进行预处理,把分辨率降低。右边的是快手,同样的视频点击“下一步”,立刻就能进入到编辑页,不需要进行预处理,这就是硬件解码器的功劳。

 

3.8 安卓硬解码存在的问题

安卓硬解码在具备以上优点的同时,也存在着很多问题:第一,安卓的机型特别多。第二,解码器的输出格式多样,性能不一。第三,支持的分辨率不一样。针对这些问题,业界常用的解决办法是黑白名单,快手一开始也做了黑白名单,但是,黑白名单是一个后置的策略,必须先知道机型,在发现有问题之后才能加到名单里,这样的操作并不智能,往往需要人工干预。快手的解决方案是跑Benchmark,自动选择最佳模式,不需要人工干预,在手机端运行测试程序选出最佳模式。

 

3.9 硬解Benchmark

3.9.1 支持哪些分辨率?

虽然手机都会声明支持哪些分辨率,但实际情况,还是要检测解码的正确性。把不同分辨率特定pattern的视频输入给解码器,检查解码出来的YUV数据正确性。

 

3.9.2 Surface输出 & Bytebuffer输出

解码器一般都支持几种输出格式,快手使用跑马策略,同样的视频输入给解码器,选择解码速度最快的输出格式。

使用了自动Benchmark后,快影的硬件解码器覆盖率,从70%提升到90%+,这是一个非常大的提升。硬解是所有流畅编辑体验的基础。

 

3.10 Seek优化

连续Seek是视频编辑操作过程中很常见的一个场景,特别容易出现卡顿的情况,需要进行大量的优化。为了达到理想的用户体验,需要做到两点:第一点,画面连续显示,这不是简单的seek,而是连续seek的过程,因此不能出现静止帧的情况;第二点,画面要能跟上手指移动的速度。

为了满足上述两点,我们设计了一个复杂而精巧的机制,能够做到保持解码器连续工作,不做重置,实现了seek跟手的流畅体验。重点讲下前向seek,也就是倒放。在保持解码器连续工作时,还可以在解码前丢弃一些非参考帧,只解码参考帧,减轻解码器的负担。这样两方面优化,可以实现流畅的前向seek体验。

 

3.11 转场优化

转场也属于编辑时常用的功能,在两段视频的交接处,往往容易卡顿,因为在渲染的时候需要两路解码。我们通过提前预热解码器的方法来解决这个问题,实现了流畅的转场预览效果。

举例上图,左右两段表示两个视频片段。左边橘色解码器解到接近交界位置的时候,创建蓝色解码器,并让其预解码几帧。当渲染转场效果时,因为蓝色解码器已经提前预解码了,此时就只有橘色的解码器在工作,整体负载比较低,就能够实现流畅的效果。

 

4. 5G的关键能力

最后说一下我们对5G的展望。5G的特点是两高一低:高带宽,数百兆甚至数十G的峰值传输带宽;低延迟,10毫秒以内的端到端延迟;高可靠,带宽和延迟非常稳定。这使得5G能够提供非常高效的通信链路。

有了这个通信链路,我们认为,就有可能把端上采集的数据,实时发给云端处理。利用云端强大的处理速度运行各类复杂的算法,把处理完的数据再实时传输到移动端显示。整个过程如果在33毫秒之内完成,就意味着达到了实时的效果。利用云端计算力可以解决手机的性能瓶颈问题。在5G的加持下,借助云端的计算力,就能实现更加复杂的AI算法和更加逼真的CG渲染效果,提供更酷炫的视频制作体验。这个未来需要5G+边缘计算结合来实现。快手会在这些新方向上持续、深入的探索。

LiveVideoStack 秋季招聘

LiveVideoStack正在招募编辑/记者/运营,与全球顶尖多媒体技术专家和LiveVideoStack年轻的伙伴一起,推动多媒体技术生态发展。同时,也欢迎你利用业余时间、远程参与内容生产。了解岗位信息请在BOSS直聘上搜索“LiveVideoStack”,或通过微信“Tony_Bao_”与主编包研交流。

欢迎关注微信公众号【纸上浅谈】,看更多音视频、OpenGL、多媒体开发文章

相关文章:

  • 如何优雅地实现一个分屏滤镜
  • OpenGLES滤镜开发 — 仿FaceU边框模糊效果
  • Android JNI Crash定位步骤
  • 2019年的第三场LiveVideoStackCon有何不同?
  • 笑死人不偿命的知乎沙雕问题排行榜
  • Android MediaCodec 硬编码 H264 文件
  • 原创|Android Jetpack Compose 最全上手指南
  • 一场微秒级的同步事故
  • 在HTML5上开发音视频应用的五种思路
  • 如何把微信打造成一个学习利器|微信阅读与笔记技巧
  • 「圣诞特辑」纯前端实现人脸识别自动佩戴圣诞帽
  • LearnOpenGL 源码在 MAC 上的编译与调试
  • 在 iOS 中使用 OpenGL ES 实现绘画板
  • 技术开发故事会连载
  • OpenGL ES 学习资源分享
  • 9月CHINA-PUB-OPENDAY技术沙龙——IPHONE
  • C++回声服务器_9-epoll边缘触发模式版本服务器
  • css选择器
  • ES学习笔记(10)--ES6中的函数和数组补漏
  • Git学习与使用心得(1)—— 初始化
  • java小心机(3)| 浅析finalize()
  • JWT究竟是什么呢?
  • Python学习之路16-使用API
  • SwizzleMethod 黑魔法
  • Yii源码解读-服务定位器(Service Locator)
  • 阿里云前端周刊 - 第 26 期
  • 创建一种深思熟虑的文化
  • 源码安装memcached和php memcache扩展
  • LevelDB 入门 —— 全面了解 LevelDB 的功能特性
  • 说说我为什么看好Spring Cloud Alibaba
  • ​软考-高级-系统架构设计师教程(清华第2版)【第20章 系统架构设计师论文写作要点(P717~728)-思维导图】​
  • #define,static,const,三种常量的区别
  • #ifdef 的技巧用法
  • #NOIP 2014# day.1 T2 联合权值
  • #QT(串口助手-界面)
  • (2.2w字)前端单元测试之Jest详解篇
  • (2020)Java后端开发----(面试题和笔试题)
  • (4)事件处理——(7)简单事件(Simple events)
  • (Note)C++中的继承方式
  • (附源码)python旅游推荐系统 毕业设计 250623
  • (附源码)springboot教学评价 毕业设计 641310
  • (附源码)计算机毕业设计ssm基于B_S的汽车售后服务管理系统
  • (免费领源码)python#django#mysql公交线路查询系统85021- 计算机毕业设计项目选题推荐
  • (收藏)Git和Repo扫盲——如何取得Android源代码
  • (未解决)macOS matplotlib 中文是方框
  • (学习日记)2024.04.10:UCOSIII第三十八节:事件实验
  • (转) SpringBoot:使用spring-boot-devtools进行热部署以及不生效的问题解决
  • .Net Memory Profiler的使用举例
  • .NET/C# 反射的的性能数据,以及高性能开发建议(反射获取 Attribute 和反射调用方法)
  • .net安装_还在用第三方安装.NET?Win10自带.NET3.5安装
  • .Net程序猿乐Android发展---(10)框架布局FrameLayout
  • .NET企业级应用架构设计系列之结尾篇
  • .net知识和学习方法系列(二十一)CLR-枚举
  • @Transactional 竟也能解决分布式事务?
  • [2016.7.Test1] T1 三进制异或