动手点关注干货不迷路
背景介绍
需求背景
屏幕共享是视频会议场景使用最广泛的功能之一,在共享一个 PPT 或者文档的情况下,人们对画面清晰度有着极高的要求,“看不清” 是最容易被用户吐槽的事情;而在共享一个视频素材的情况下,大家又对流畅度有着极高的要求,“卡顿” 也是最容易被用户吐槽的点。
为了更好地同时满足用户对清晰度和流畅度的要求,视频会议软件通常会设计两种模式:
- 清晰模式:主打清晰度,尽量保持高分辨率(如:最高 4K 原画质),带宽或性能不足的时候,只降低帧率(如:从 30fps -> 5fps),不降低分辨率。
- 流畅模式:主打流畅度,尽量提升帧率(如:最高 30fps),带宽或性能不足的时候,优先降低分辨率(如:从 4K -> 720p),最后才考虑降帧率。通常情况下,默认选择“清晰模式”,当用户要共享视频的时候,需要自己 “手动” 点击勾选上 “流畅度优先”按钮。
一种简单的方案是根据用户共享内容的文件后缀名来决定是“清晰度优先”还是“流畅度优先”,比如共享 PPT 时自动切换为“清晰模式”,共享视频时自动切换为“流畅模式”,但是这样设计会遇到一些问题:比如用户的 PPT 里嵌入了一段视频,在播放这段视频时理应追求“流畅度优先”;而如果用户视频其实是一段 PPT 的教学录屏,里面有大量的时间在播放静止的文字和画面,这时候“流畅模式”则会导致这些关键内容显得模糊。
RTC 要如何帮助用户及时调整最佳的共享模式呢?
需求分析
需求功能分析 痛点:
用户分享视频内容需要高帧率,而文字/ppt 需要高清晰度,这两种场景的需求是互相矛盾的,如果需要用户手动勾选相应的共享模式,不仅操作繁琐,也容易漏选、错选。
如何解决:
需要研发一个算法自动识别共享内容,进而确定当前是需要高帧率还是需要高清晰度。这样,在用户想要清晰画面的时候,产品就提供清晰的画面,用户想要流畅的视频体验时,产品就尽可能地保障屏幕画面的流畅性,用户在无感知的情况下就能获得当前场景的最佳体验。
屏幕共享场景定义 清晰度优先的场景
以文字为主,用户更需要看清楚画面的边缘特征,而较少关注其运动特征。
流畅度优先的场景
以视频内容为主,用户更需要流畅连贯的动态画面,而较少关注于单帧的清晰度。
技术实现 算法原理
学界相关成果概述 目前我们参考了以下两篇参考文献。第一篇是 Jing, Wang & Xuetao, Guan & Yang, Zhang. (2013). An Adaptive Encoding Application Sharing System Based on Remote Display. 266-269. 10.1109/ISDEA.2012.66.
该论文主要假定视频区域的均会以 24-30FPS 的频率发生变化,用 N*N 的 patch 的形式进行检测,从而发现视频区域。
第二篇参考文献是,侯文慧, 王俊峰. 面向云桌面协议的视频区域侦测算法[J]. 计算机应用, 2018, 038(005):1463-1469,1487.
这篇论文主要通过高变化区域侦测,并利用传统 sobel 算子+膨胀算法的边缘检测发现可能的矩形区域,通过颜色直方图的颜色数量判定文本区域从而确定视频内容区域。
相关算法的介绍
- 光流
(光流示意,引用自:https://medium.com/axinc-ai/raft-a-machine-learning-model-for-estimating-optical-flow-6ab6d077e178)
光流法实际是通过检测图像像素点随时间的变化进而推断出物体移动速度及方向的方法。假设该移动很小,那么可以根据泰勒级数得出:
文章图片
因此可以推出
文章图片
最终可得出光流方程:
文章图片
文章图片
这个方程有两个未知数,不能直接进行求解,这被称为光流算法的孔径问题。为了求解光流方程,还需要另一组方程,这个方程由附加的约束给出。(以上内容引用自 wikipedia)
文章图片
孔径问题
(孔径问题示意,引用自:https://zhuanlan.zhihu.com/p/74460341)
假设:
- 相邻帧之间的亮度恒定;
- 相邻视频帧的取帧时间连续,或者,相邻帧之间物体的运动比较“微小”;
- 决策树
文章图片
- 【算法|RTC 场景下的屏幕共享优化实践】决策树易于理解和解释,可以可视化分析,容易提取出规则;
- 可以同时处理标称型和数值型数据;
- 比较适合处理有缺失属性的样本;
- 能够处理不相关的特征;
- 测试数据集时,运行速度比较快;
- 在相对短的时间内能够对大型数据源做出可行且效果良好的结果。(引用自 wikipedia)
- 颜色直方图
文章图片
- 方向统计(Directional Statistics)
Directional statistics (also circular statistics or spherical statistics) is the subdiscipline of statistics that deals with directions (unit vectors in R(n)), axes (lines through the origin in R(n)) or rotations in R(n). More generally, directional statistics deals with observations on compact Riemannian manifolds including the Stiefel manifold. The fact that 0 degrees and 360 degrees are identical angles, so that for example 180 degrees is not a sensible mean of 2 degrees and 358 degrees, provides one illustration that special statistical methods are required for the analysis of some types of data (in this case, angular data). Other examples of data that may be regarded as directional include statistics involving temporal periods (e.g. time of day, week, month, year, etc.), compass directions, dihedral angles in molecules, orientations, rotations and so on. (引用自 wikipedia)利用方向统计方法,能够准确地统计出向量样本的方向均值,以及方向的离散程度,也避免了传统统计方法在角度值统计计算上的误差。
举个简单的例子,如下图所示,7/4π 和 1/4π 统计均值,以传统方法计算为 π,而利用方向统计就可以得到出均值为 0 的结果。
文章图片
算法总流程设计 视频的定义就是运动的画面,但在屏幕共享当中,并不能够将运动的画面都当作视频内容来处理。实际使用中,需要将部分运动的画面识别为需要高清优先、流畅度其次的屏幕内容,保证用户在此时获得清晰的观看体验。
- 探索性数据分析(EDA)
文章图片
文章图片
- 算法流程图
三个模块分别是:
- 运动幅度分析:主要进行运动幅度相关特征的提取,能够统计运动画面比例,去除一些噪音。
- 运动角度分析:主要进行运动角度相关特征的提取,能够统计画面运动的方向,以及运动方向的分散程度等
- 纹理特征分析:主要提取一些纹理相关的特征,判定当前区域是否为文字区域。
- 采样:光流算法需要前后两帧数据进行计算,需要对视频流进行采样,得到两帧数据
- 光流计算:计算出全图的稠密光流
- 特征提取:提取运动和纹理特征
- 状态转移:通过一系列模式和规则进行状态转移
- 输出结果:根据内部状态信息输出检测结果
文章图片
算法参数优化与评价
数据采集和标注 由于数据集非常匮乏,需要我们自己高效地获取一批人工标注数据,进行参数的优化和算法的测试。我们自己录了一些数据,并开发了一个小型的标注软件,进行了数据标注工作。
算法评价指标
文章图片
(图片来源:https://en.wikipedia.org/wiki/Sensitivity_and_specificity)
- 准确率 (precision)
文章图片
- 召回率(recall)
文章图片
内容识别算法需要在准确率和召回率之间进行权衡,根据业务场景调整检测结果偏好。
算法实现与优化
算法实现 光流计算
稠密光流的计算目前有两种常见算法,HS 光流,DIS 光流 在实现上,选用了 DIS 光流估计的方法,两种方法在相同机器上运行时间如下表所示。
算法 | 分辨率 | 计算时间 |
---|---|---|
DIS 光流 | 320x180 | 7ms |
HS 光流 | 320x180 | 13ms |
文章图片
(DIS 光流法计算准确度与运算时长相较其他算法比较,引用自 Kroeger, Till & Timofte, Radu & Dai, Dengxin & Van Gool, Luc. (2016). Fast Optical Flow Using Dense Inverse Search. LNCS. 9908. 471-488. 10.1007/978-3-319-46493-0_29. )
特征提取
在计算光流之后,我们需要提取运动幅度,运动角度以及纹理相关的特征。
在计算光流之后,提取运动幅度、运动角度以及纹理相关的特征。
- 坐标系转化:笛卡尔系->极坐标系
- 纹理计算
- 角度特征的提取
状态转移
利用决策树,经过一些剪枝处理后,获得了一些强特征的阈值,比如运动的角度均值,运动的角度离散度等,这些阈值都具有非常显著的可解释性。在状态转移模块中,使用内置的一个概率值记录状态,然后根据上述基于机器学习的规则对概率值进行调整,再结合业务融合一些人工特征,最终根据概率值的变化转移模块的状态。
计算开销优化 虽然该算法能够以较快的速度对视频帧进行处理,但实际的屏幕共享中,对计算机资源的消耗也有更加严格的要求。那么就需要对检测的的策略进行细致的优化,够进一步降低 CPU 占用和耗电量。
- 计算量与运算速度
算法 | 分辨率 | 运行时间 |
---|---|---|
DIS(MEDIUM) | 320x180 | 7ms |
DIS(FAST) | 320x180 | 4ms |
DIS(ULTRA FAST) | 320x180 | 1 ms |
Accuracy | Recall | Precision |
---|---|---|
0.9524 | 0.9608 | 0.9756 |
- 计算频率优化与静默模式
在权衡响应时间和 CPU 占用后,直接大幅度降低检测频率,比如每隔 5 帧检测一次,在这种策略下,响应时间和 CPU 占用都处于一种比较好的状态。
但是,这种较低的检测速度依旧会带来可察觉的 CPU 增量,能不能再极致一点呢?
考虑到常见的办公场景,用户在屏幕共享时,其内容类型在较长的时间内是保持不变的,所以检测的结果也应该是长时间保持不变。假如是我们人类在这种情况下,在做这样的分类结果一直不变的任务时,可不可以稍稍偷偷懒呢?答案是肯定的,那么计算机应该也可以在这种情况下“偷一下懒”。这样就可以在算法中引入了静默的概念,当检测的结果基本不变时,检测算法模块开始进入静默状态,此时检测降低到更低的频率,这样 CPU 占用增长基本就察觉不到了。
如何确定何时需要进入静默呢?算法利用时域上的积分求得一个分数,当该分数达到一定阈值的时候,并且满足一些其它的限制条件的时候,就可以认为检测到的为同一种类型了,就可以开始降低检测频率。这样就保证了大多数情况下 CPU 的极低开销,并且也尽可能保留了算法快速响应的特性。
功能实现
决策逻辑 在共享模式的决策逻辑的设计上,需要明确两点:
- 尽可能保持稳定的分辨率与编码策略,减少编解码器重启带来的开销
- 适当的切换速度
由于视频流传输的过程中,在有限的带宽下,往往需要将帧率和分辨率相匹配以获得合适的带宽消耗。
所以自动模式预设了若干个帧率和分辨率相匹配的档位,在每次获得检测算法的检测结果后对帧率进行增减,再根据帧率的大小匹配相应的分辨率。在帧率下降的时候,就可以根据内外部条件的限制升高传输分辨率;相反,在帧率上升的时候,就可以用适当的逻辑对分辨率进行降级操作。
2. 编码方式决策
在共享文字场景为主的屏幕内容时,编码策略也会与流畅度优先的视频编码方式不同,这时会使用专门的针对屏幕内容的编码器,并开启重复帧检测等策略,同时也会对码控策略进行场景化的调整,从而使画面更符合用户需求。
3. 抗抖动
策略的切换一般是需要需要响应时间的,比如分辨率的切换和编码策略的切换都会有一定的响应时间,如果频繁的切换就会造成卡顿。
为了在发生抖动的情况下,依旧能够保证良好的共享体验,需要引入一些抗抖动的机制。
- 抖动主要来自于两个方面
- 误检测造成抖动
- 真实的共享内容频繁切换导致抖动
- 误检测造成抖动
- 在整个 pipeline 的设计上,设计一种负反馈的调节机制。如前文所述,在帧率越高时,光流估计越准确,而帧率低时,不准确的光流估计容易将一般的文档场景误检测成视频播放的场景。当检测出一次内容变化时,如果是因为输入帧率低导致误检,这个时候及时提高帧率又能够降低误检概率,这样就可以避免由于误检导致的共享模式的切换,促成检测速度和准确度的稳态。
- 通过控制决策频率来抑制抖动的现象。
文章图片
在这种机制下,分辨率就不会随着帧率进行频繁地切换,能够更好地保证用户体验。
功能特色 业务实践
在飞书屏幕共享的流畅度优先模式中率先启用了该功能,在业务上称为智能流畅模式,这样在用户就能够在播放视频时达到 30fps 的流畅度,在共享文档/ppt 内容时,又能保持较高的清晰度。这个功能基本解决了用户错选流畅度优先造成的清晰度不符合需求的问题,同时又保证了在用户在真正需要流畅度体验的时候,得到高帧率的体验。
落地效果
经过大范围的线上测试之后,通过统计数据可以发现,采用“屏幕共享自动模式”后,一些原本采用“流畅模式”的共享场景被算法模块纠正为了“清晰模式”,同时通过下图可以发现,用户的屏幕分享分辨率有了极大地提升,得到了显著的清晰度提升。在线上算法的判定的准确程度上,通过对用户反馈的统计,该功能也有着比较好的评价。
文章图片
同时通过统计数据可以发现,得益于采集和编码帧率的下降,CPU 占用不仅没有上升反而得到了一定的优化,如下图所示,开启自动模式的功能之后,最高可以得到 CPU 占用降低 20%的收益。
文章图片
与其他候选方案的比较
在研发之初,我们也调研了一些候选方案,一种技术方案是使用像素差异与变化的占比作为切换依据,这样最大的问题是,在部分教学视频或说明类内容中,在视频内容中展示 ppt 场景时,算法会出现误判,将肉眼感知到的静态场景检测为视频场景,画面清晰度下降,不符合用户使用的直觉;此外还有一种方案是针对应用类型进行适配,比如根据进程名称和窗口大小进行策略调整,这样虽然能够解决用户场景化的需求差异,但是对于算法与策略的通用性会有较大的挑战。本文使用的这套算法就能够避开了上述的问题,体验更加友好。
未来的演进与规划 算法演进
虽然由于数据集的相对缺乏,在设计之初排除了深度学习模型的应用。在研发过程中,对算法流程与模块进行拆分,其中独立出的纹理分析等模块,这样就可以通过人工数据集的方式,在部分算法模块尝试应用深度学习模型,以期能够获得更好的算法表现。同时,考虑到当前的算法还是针对全局画面的分类,未来会推出视频区域的 ROI 检测,这样能够让下游应用具有更强的灵活性和对业务的适应能力。
业务演进
当前屏幕内容检测算法支持了共享模式的切换,此外,利用屏幕内容检测算法,还可以对发送端和接收端的网络策略进行更智能的调优,以期在文档、ppt 场景下,进一步减少屏幕共享的延时与卡顿,让投屏与屏幕共享响应更高清、更流畅、延时更低,给用户提供更好的沉浸式体验,带来更显著的生产力的飞跃。
加入我们
字节跳动 RTC 团队,作为全球领先的音视频团队,我们致力于提供全球互联网范围内高品质、低延时的实时音视频通信能力,目前已经支撑了抖音、TikTok、清北网校、字节系游戏,视频会议等多个场景的应用,服务 10 亿用户,用户遍布全球每一个角落。
我们是 RTC Lab 部门,负责 RTC 产品中音频、视频、网络等基础功能的研发,通过极致的工程和音视频算法,打磨顶级的实时音视频基础体验,期待优秀同学的加入 点击“阅读原文“链接,加入我们吧!
文章图片
点击“阅读原文”,一键投递简历!
推荐阅读
- 大数据|抖音 Android 性能优化系列(Java 锁优化)
- 设计模式|深入浅出依赖注入及其在抖音直播中的应用
- java|MemoryThrashing(抖音直播解决内存抖动实践)
- 算法|RTC 性能自动化工具在内存优化场景下的实践
- 大数据|抖音 iOS 推荐 Feed 容器化总结
- 算法|KMP算法、计算器(一)、(二)
- 中间件|【实战篇】egg+vue+mongodb实践开发在线文档管理平台——水墨文档
- Python|基于PyTorch的flappy bird游戏
- java|Java 应用线上问题排查思路、常用工具小结