前言
视频典型画面不失常次要蕴含画面卡顿、画面含糊、画面不显示、画面花屏这 4 类问题。本文次要介绍的是画面花屏的状况,这里的画面花屏蕴含了花屏、闪屏、绿屏、黑屏。视频花屏是多媒体工程师最常见的问题之一,也是最辣手的问题之一,笔者此前也数次遇到这样的问题,明天在此总结分享下教训,心愿浏览到这篇文章的小伙伴们都可能有所播种。
问题定位
很多小伙伴碰到此类问题,往往感觉大刀阔斧,实质起因还是对于视频链路不太清晰,导致无从下手。当遇到视频花屏时,首先要定位是最先呈现的花屏的是哪个阶段产生的,再逐层进行剖析定位。以 RTC 视频为例,分为发送端、服务器、接收端,其具体流程如下:
如果发现对端显示不失常,排查程序:
(1)排查接收端;
(2)排查发送端;
(3)排查服务器;
如果发现是本端显示不失常,排查程序:
(1)排查发送端;
(2)其次是分环节排查。
接收端流程
-
播放器流程
rtmp- 解协定 - 解码 - 后处理 - 渲染。
mp4/flv- 解封装 - 解码 - 后处理 - 渲染。
播放器数据起源来自网络视频或者本地视频。
如果本地视频呈现问题,能够先应用其余播放器 VLC/ffplay 播放本地的视频看看。
如果网络视频呈现问题,能够保留解码前的数据,应用 ffplay 播放 h264 试试。
依据播放器的 2 种流程,还有可能在解协定或者解封装的阶段,因而能够在这之后 dump h264 码流看看。
- WebRTC 接收端流程
rtp-jitterbuffer- 解码 - 后处理 - 渲染。
网络局部:嵌入式设施用了 webrtc,其网卡对于带宽限度重大,会造成数据包失落重大;另外就是理论网络状况差,导致接收端数据包失落重大;都有可能导致生成的画面花屏。
解码局部:硬件解码容易出错,一是硬件解码器会因各种厂商定制化存在差别,兼容性问题多,容易呈现报错的状况,二是 YUV 格局的不同,软解个别是 YUV420p,硬解是 NV12 等,对于解码器的格局指定,须要关注解码器自身的能力。咱们还能够在解码之后 dump YUV 数据来查看具体的状况,如果播放 dump 之后的数据存在绿屏、花屏,有可能是内存对齐的问题,也有可能是 dump 格局不对,或者是硬件解码器的问题。
后处理局部:图像格式转换、opengl 内存对齐、GPU 数据多线程同步问题等。
渲染局部:渲染呈现色调偏差,有可能是图像格式转换的计算公式上的偏差,也有可能是 opengl 内存对齐的问题。画面裂屏有可能是渲染脏数据的问题,次要起因是 GPU 数据的多线程同步问题。
发送端流程
- 采集环节:自身摄像头进去的数据就存在异样,属于硬件采集设施异样,特地是一些 USB 内部摄像头;其次就是采集原始格局如 MJPEG 格局,Pipeline 上在采集模块将 MJPEG 转为 I420,图像格式转换也有可能导致数据异样。
- 回调环节:将采集数据回调内部,内部进行二次解决,如美颜等,也有可能导致数据异样,常见的就是画面黑屏、闪屏等景象,次要是因为内部模块因为 OpenGL 出错,导致给出的 GPU 数据没有填充等起因。
- 前解决环节:包含图像格式的转换和 GPU 纹理渲染都有可能存在异样,以及相干的前解决视频算法。
- 编码环节:dump h264 码流,排查编码引入的问题。
- 本地预览环节:包含图像格式的转换和 GPU 纹理渲染都有可能存在异样。
- 发送环节:udp 发送,有可能存在丢包状况;弱网导致队列呈现了数据沉积,并产生了 drop 数据的状况;短时间发送大量数据,如 I 帧的迅速发送。
- dump 环节:通常咱们通过 YUV dump 排查具体是上述哪个环节引入的问题,但对于 dump 自身也有可能存在问题,例如 dump 的格局和理论大小的尺寸,在播放时设置不统一,就会呈现问题。
服务器转发
- 级联环节:级联层级之间如果存在编解码行为(服务器转码),也会引入危险。
- 缓冲环节:队列溢出,也会引入危险。
在排查发送端失常的状况下,可察看服务器转发环节:
- SRS 环节:用户 1 拉到的流失常,阐明 SRS 环节失常,否则就阐明 SRS 服务器存在问题。
- 阿里 CDN 环节:用户 2 不失常阐明阿里 CDN 环节存在问题。
- 腾讯 CDN 环节:用户 3 失常,用户 4 不失常,阐明是 CDN2 环节存在问题。
起因剖析
在上述问题定位之后,咱们能够大抵确定是哪一环节引入的画面异常现象,此时咱们就能够针对这个环节进行起因剖析,剖析具体是什么起因导致的这种画面异样。
花屏起因
- 失落参考帧
个别 H.264 码流有 I、B、P 三种帧类型,I 帧是关键帧,B 帧是双向预测编码帧,P 帧是前向预测编码帧。
I 帧因为是帧内压缩,因而能够独立解码播放,而 B 帧,一旦失落了 I 帧或者前面的 P 帧,则会解码失败,而 P 帧一旦失落了后面的 I/B/P 帧,也会导致解码失败。对于失落了参考帧而导致的解码失败,个别就会呈现花屏的景象,花屏的重大水平依赖于失落的参考帧对行将解码的帧的重要水平。首先,推流 / 播放的代码层面,须要留神,不要抛弃编码后、解码前的视频帧数据。不过理论场景中,遇到上面的状况,不免还是会产生丢帧:网络不好,编码后的数据发不进来;零碎低内存,队列外面无奈接受更多的帧数据。因而,在这些极其的状况下,不得不丢帧的话,最正当的策略就应该是一次丢一整个 GOP,即:一旦开始丢了一个 I 帧,那么在遇到下一个 I 帧之前的所有视频帧,均抛弃掉,这样即可无效防止播放器端产生解码花屏。
- 播放器没有从关键帧开始解码
原理仍然如下面所述,如果不从关键帧开始解码,则必然会因为失落了参考信息而导致解码花屏。因而,播放器,无论是首播,还是断网重连后,都应该判断第一帧视频是否是关键帧,如果不是,则应该等到第一个关键帧达到之后再送入解码器。
- 码流中视频尺寸发生变化
很多直播 App,横屏直播和竖屏直播,应用的是不同的推流尺寸,当主播由竖屏推流改为横屏推流,同时又不扭转推流地址的话,观众端拉到的流就会呈现两头产生了视频尺寸的变动,比方:从 720 x 1280 变成了 1280 x 720 等等。播放器须要实时检测,如果发现视频尺寸产生了变动,则须要重置解码器以及相干逻辑,否则容易呈现解码花屏或者呈现内存越界等异样。
- 硬编硬解的兼容性问题
当然,如果应用的是 Android 硬编硬解,则难免会遇到一些比拟坑爹的手机,硬编硬解没有失败报错,然而输入的图像的确异样的状况。Android 硬编硬解的兼容性问题,代码上小心认真,充分考虑机型的兼容性,不轻易写死任何参数,剩下能做的就是靠白名单 / 黑名单了。硬编硬解还有 16 字节对齐的问题。还有可能是视频多 slice 的问题,在解码端没有兼容这种状况,导致的花屏问题。
- 推流端图像尺寸和格局处理不当
图像的格局和尺寸,都是十分重要的参数,肯定要严格配置正确。比方:如果采集到的视频是 NV21,编码器只反对 I420,那么编码进去的图像天然会呈现色彩问题。比方:在一些场景切换的过程中,前后摄像头切换,视频的尺寸可能产生了变动,然而剪裁、解决、编码模块没有相应的批改尺寸,那么,也会呈现各种视频错乱的景象。
- 图像格式转换
在视频编解码中必然会波及到 YUV 和 RGB 图像格式的转换,并且 YUV 还有多种格局。如果转换格局或者算法不正确也会引发视频花屏问题。此问题产生在视频渲染或者视频解决阶段。由 YUV 与 RGB 图像格式转换引发的花屏景象有很多无奈判断,然而有一种状况根本能够断定是因为此起因引发的:
(1)图像的黑白数据是失常的,然而色调不失常,比方色调偏色、甚至错乱。
(2)图像整体仍然处于可辨认的状态,然而存在显著的黑白斑块。
(3)图像看起来都失常,然而认真比照色调,略有偏差,次要 YUV 多种格局和 RGB 之间的转换,须要留神转换矩阵的差异性。
- 渲染脏数据
渲染脏数据是还未实现渲染的数据。具体来讲就是在视频帧渲染到一半的时候,即被送到后续环节。此问题产生在视频渲染(包含离屏渲染)阶段。这类问题能够归为 GPU 数据的多线程问题。
(1)图像具备显著的撕裂或者错位特色,渲染脏数据造成后果就是该图像一半是以后帧的数据,另一半是上一帧的数据。
(2)渲染脏数据通常不会造成继续型的花屏景象。
- YUV Stride 对齐问题
针对内部渲染没有按理论的 Stride 值进行数据读取渲染,而是依照 Width 读取,就会呈现画面内容失常,uv 色调问题。对于解码之后的视频数据 dump,如果解码后的 Stride 值大于 Width 时,那么 dump 的 YUV 数据就会存在绿边的状况。这些都属于内存对齐的领域。在 Android 局部机型的硬件编码上也呈现过,编码之后的数据 uv 显示异样的状况。
闪屏起因
闪屏问题,从本源来看,就是播放的过程中,呈现了两种不同的画面来回切换,从而看起来像「闪屏」,比方,黑白两张图片交替渲染。
- 播放器缓冲机制起因
网络不好的时候,播放器会频繁缓冲,曾遇到过一种案例,就是某直播 App 利用,在缓冲的时候,应用了一张广告图片,在某种极其弱网状况下,因为频繁缓冲,导致实在的播放画面和广告图片来回疾速切换,导致闪屏景象。
这个状况是齐全能够从播放器的缓冲策略上防止的,每次缓冲后,不要收到一帧后就立刻渲染,而是适当地多缓冲一些数据,再发送缓冲完结的音讯,从而能够频繁 ms 级别的缓冲切换产生的闪屏。
- 推流端的起因
推流端产生闪屏的流,往往产生在有画面合成的代码模块,比方:叠加水印、摄像头 / 图片切换推流、连麦合流等等。画面的合成,肯定要铭刻一点,任何状况下,都要避免出现,有合成 / 没有合成两种画面的交替。
- GPU 数据的缓存问题
特地是像应用 PBO 双缓存处理不当;先前纹理数据和现有纹理交替应用问题。如果某个功能模块一直开关,功能模块没解决纹理缓存,因为纹理往往是复用的,会导致敞开性能,保留最初一帧,过一段时间再开启性能,因为 CPU 到 GPU 的异步起因,并不能立刻应用最新的视频帧,有可能还是上一次的视频帧,从而呈现闪屏问题。
- 生产 Sink 挂载问题
如果 2 个数据源往同一个生产 Sink 输送数据的时候,就会呈现显著的闪屏问题。
绿屏起因
- 局部 USB 摄像头偶现异样,呈现画面绿屏的状况。
- 视频多 slice 的问题,在解码端没有兼容这种状况,导致的绿屏问题。
- 解码出错显示绿屏。
黑屏起因
- 主播端摄像头权限问题
无论 Android 还是 iOS,App 应用摄像头都是须要申请受权的,特地是 Android 6.0 当前,如果 App 层面不做专门的解决的话,很可能呈现摄像头权限被禁用的状况。如果 App 没有获取到摄像头权限,视频就无奈采集胜利,从而导致推出来的流只有音频数据。解决方案:App 层面必定要小心解决权限问题,检测到未获取相应权限则禁止开播,或者重复提醒主播授予权限。另外,能够询问呈现问题的主播是否有摄像头预览画面,如果 App 没有取得权限的话,是没有预览画面的。
- 摄像头出帧问题
摄像头启动的前几帧,会因为相机曝光的问题,呈现画面亮度不够的状况,这种景象很常见。Android 设施,零碎 rom 问题,抉择高帧率时候相机画面解决有问题,可能会出黑帧的状况。
- 主播端编码失败
视频数据采集到后,下一步就是通过编码器,因为参数配置或者某些机型的硬编兼容性问题,很可能数据送入编码器后,编码失败,并无输入,从而导致没有视频数据送入到推流模块。解决方案:个别推流 SDK 都会统计推流的实时视频帧率,CDN 服务端也会有一些帧率监控,因而,如果发现这些统计失去的推流帧率为 0,同时又确定不是没有采集到数据,那么多半是编码器的起因,能够想方法查看下该机型的日志看看具体的报错信息。
- 视频画布问题
没有正确设置画布挂载,或者画布不可见,都无奈使用户看到画面。视频渲染异样,导致无奈正确渲染画面,从而黑屏。
- 视频解码失败
当播放器遇到不反对的视频格式,或者数据内容 / 格局异样,则会解码失败,从而导致无解码视频输入。针对不反对的格局:要提前理解播放器自身反对哪些音视频格局,如 H.264,mp4v,aac 等等,防止播放不反对的格局。播放器自身遇到的硬解或者软解失败,应该有日志报错,或者抛出异样给应用层提醒用户,针对视频数据内容谬误,须要剖析码流文件自身,常见的数据内容谬误导致的解码失败有如下几种:
(1)送入解码器的帧数据不残缺。
(2)H.264 的视频码流,缺失了 SPS,PPS 等必要的信息头。
(3)iOS 的 VideoToolbox 解码,只反对 avcc 形式打包的 H.264 数据。
(4)局部 Android 机型硬编出来的数据有额定的 naul 头。
(5)视频的多 slice 问题没有兼容。
- GPU 操作异样
纹理和绘制窗口的数据都是一段内存,内存创立之后,默认值都是 0,而 RGBA 对应的色彩是 0 就是黑屏。
因而呈现黑屏的状况有如下状况:
(1)没有正确设置视口(Viewport):OpenGL 须要晓得渲染区域的大小和地位,如果视口设置谬误,可能会导致黑屏。
(2)没有正确设置投影矩阵(Projection Matrix):投影矩阵决定了物体在屏幕上的地位和大小,如果投影矩阵设置谬误,可能会导致黑屏。
(3)没有正确设置模型视图矩阵(Model-View Matrix):模型视图矩阵决定了物体在世界坐标系中的地位、旋转和缩放,如果设置谬误,可能会导致黑屏。
(4)没有正确启用深度缓冲区(Depth Buffer):深度缓冲区能够避免远处的物体遮挡近处的物体,如果没有启用深度缓冲区,可能会导致黑屏。
(5)没有正确清空色彩缓冲区和深度缓冲区:在每次绘制前,应该清空色彩缓冲区和深度缓冲区,如果没有清空,可能会导致黑屏。
(6)着色器谬误:着色器程序可能存在谬误,例如顶点着色器或片段着色器编译谬误、链接谬误等,导致黑屏。
(7)应用了谬误的纹理格局:如果应用了谬误的纹理格局,可能会导致黑屏。例如,应用 OpenGL ES 2.0 时,不能应用压缩纹理格局,否则会导致黑屏。
(8)渲染一个空纹理,或者没有正确绑定应用的 FBO,有可能就是黑屏;
(9)在不同的线程中,没有应用共享的 OpenGL 上下文,会导致纹理数据无奈在跨线程中应用。
(10)在没有上下文环境中,应用 GL 操作等到的后果,会是黑屏。
总结
视频异样画面是有数音视频从业者都须要面对的问题,如何高效定位剖析,是晋升此类问题排查效率最无效的伎俩。心愿通过这篇系统性的文章讲述,可能帮忙平时有纳闷的小伙伴们。千里之行始于足下,面对盘根错节的问题时,往往须要咱们抽丝剥茧,把握事物的实质,能力更好的去翻新。