my_life

http://ticktick.blog.51cto.com/823160/1722446

 

1. 视频码率一般设多大?

 

对于1080P的视频而言,蓝光视频的码率是20Mb/s,一般下载的视频码率大都是10Mb/s,一些IPCamera/无人机的码率是2~8Mb/s,而很多视频网站的码率甚至低于5M/s。

 

同等分辨率的情况下,码率越大,清晰度越大,但同时对网络带宽的占用也越大,具体码率该设置为多少,需要看应用的具体场景了。

 

2. 播放中出现“跳跃”和“花屏”现象?

 

“跳跃”和“花屏”现象绝大多数原因是网络传输过程中由于信号不好导致丢失了“关键帧”/“参考帧” 引起的,下面来进一步解释。

 

视频在网上传播之前是需要压缩的,而简单来解释视频压缩的核心思想就是:每隔10~50帧取视频中的一帧图像作为“关键帧”,而随后的几帧图像由于时间/空间的冗余和相关性,我们只需记录其与关键帧的“差异”信息即可,这样视频文件就可以不用把每一帧完整的图像数据全部保存下来,从而起到了节省空间的效果。

 

由此可见,如果丢失掉了“关键帧”,随后的几帧图像自然就无法正常地解码了,因此产生了“花屏”现象。

 

从技术的角度,怎么解决“花屏”现象呢?——当我们在视频传输过程中,通过帧序号发现丢帧后,可以跳过随后的非“关键帧”,直到遇到下一个关键帧再送入解码。这样的确可以解决“花屏”现象,但是由于跳跃了很多帧,因此会出现视频图像的不连续情况(即“跳跃”现象)。

 

3. 播放过程中出现“卡顿”现象?

 

由于网络是很不稳定的,因此,音视频数据的传输也是时快时慢的,在播放网络视频流的过程中,一定要根据时间戳来决定何时解码何时显示,而不是来一帧就播放一帧,另外,添加一定数量的“帧缓冲区”可以有效地降低由于网络抖动带来的“卡顿”现象。

 

4. 音视频实时传输的延时主要来自哪里 ?

 

(1) 编码器/解码器一般需要缓冲2~4帧

(2) 编码/解码的耗时

(3) 业务代码中的帧缓冲区

(4) 网络传输延时

(5) 代码中的数据拷贝

 

一般情况下,帧率为30f/s的视频,每缓冲n帧,就会增加1000/30*n毫秒的延时。因此,要想减少延时,则必须通过分析和测试找到上述每一部分的延时,尽量减少数据的拷贝和缓冲。

 

5. 边下边播的原理 ?

 

边下边播与播放本地文件其实差不多,只不过是文件数据不在本地,在播放器播放到指定位置之前,后台线程把需要的数据提前下载下来而已。

 

关于Android中使用开发HTTP边下边播的功能,可以参考我的这篇文章:《Android HTTP边下边播》

====

2. 播放问题的排查工具

一旦我们遇到视频播放不了,第一件事,就是要找几个别的播放器也播放看看,做一下对比测试,或者对码流做一些基础分析,以便更好地定位问题的源头,各个平台比较常见的播放/分析工具有如下几个:

2.1 命令行工具

ffplay,ffprobe,mediainfo,hls-analyzer 等

2.2 网页端工具

http://www.cutv.com/demo/live_test.swf

http://www.ossrs.net/players/srs_player.html

2.3 App 应用

vlc,vplayer,mxplayer 等

2.4 Windows 工具 

mp4info,FlvParse,FLVMeta,Elecard StreamEye Studio 等

 

3.5 只有音频没有视频,或者只有视频没有音频

出现该错误的原因可能有如下几点:

- 音频/视频的编码格式不支持,导致解码失败

- 音频/视频的数据内容异常,导致解码失败

- 基于 ffmpeg 的播放器的 `probesize` 设置太小,导致解析码流信息不足

- 码流/文件本身的前半段只有音频没有视频,或者只有视频没有音频

 

主播端网络不好,直接影响到的就是千千万万的观众,因此,如果发现所有的观众都出现频繁卡顿,那么多半就是主播端的问题了。

用带宽测试工具:http://www.speedtest.net/ 测试下主播的带宽,如果主播的上行带宽明显小于推流的码率,那么肯定会出现推流帧率不稳定。

 

观众是整个直播的终端环节,一般如果不是大面积的观众出现卡顿,那么很可能是这个观众自身的网络问题

 

2.3 视频流时间戳问题

这个问题也遇到的比较多,特别是客户自己写的推流 SDK 或者码流经过一些转码处理后,没有处理好音视频时间戳从而产生的问题。播放器一般是严格根据码流中的音视频的时间戳来做音画同步的,因此,如果码流中的音视频时间戳出现错误,肯定会影响到播放画面的渲染时机。

例如,曾经遇到一个流的时间戳信息如下:

wKiom1j_Mm2RpqdyAAIWJyjJMK0112.png

可以看到,它的视频时间戳出现了 “回退”,而播放器一般 master 主时钟是单调递增的,当后来的视频帧小于了当前的主时钟,播放器就会做丢帧处理,从而导致播放的视频帧率远低于实际码流中的视频帧率,从而产生卡顿现象。

 

http://ticktick.blog.51cto.com/823160/1924289

1. 延时的测量

一般测量延时最简单的方法,就是推流端和播放端对着同一个时钟,然后用播放端显示的时间减去推流端显示的时间,就得到了粗略的直播延时。

2. 延时高问题分析

首先,我们看看可能产生延时的模块有哪些:

- 图像处理延时,比如画面剪裁、美颜、特效处理

- 视频编码/解码延时

- 网络传输的延时

- 业务代码中的缓冲区

 

一般图像处理、数据拷贝、编解码带来的延时,都是 ms 级别的,真正会产生比较大延时的地方,一个是互联网上的网络传输延时,另一个就是业务代码中的缓冲区了

 

2.1 网络传输延时

数据在网络上传输,从一个节点经过多级服务器转发到达另一个节点,是不可避免有物理延时的,下面这个表格给出了理论上数据在光纤中的网络传输的时间(实际场景中的延时往往比这个要大很多,因为涉及到带宽、网络抖动等干扰):

 

wKioL1kTI03wzmHjABHJjafeWag255.png

 

由该表可以看出:播放端离推流端或者边缘服务器节点的物理距离越近,延时会越小。

 

2.2 业务代码中的缓冲区

业务代码中的缓冲区,主要是推流端的缓冲区和播放端的缓冲区,一个 30 fps 的视频流,缓冲区每滞留 30 帧,延时就会增大 1s,那么,它们是怎么产生缓冲数据的呢 ?

 

- 推流端的数据是怎么 “积累” 起来的 ?

采集 -> 编码 -> 数据发送 -> [服务器]

当网络产生抖动的时候,“数据发送” 会因此减慢,产生一定的阻塞,从而导致这些数据会被 “积累” 在了推流端的发送缓冲区中。

 

- 播放端的数据怎么 “积累” 起来的 ?

[服务器]-> 数据接收 -> 解码 -> 渲染

当网络产生抖动的时候,服务器的数据无法 “及时” 地传输到播放端,而由于 TCP 协议的可靠性,所有的数据都会被服务端积累起来,在网络恢复良好的时候,会快速传输到播放端,这些数据会被动地  “积累” 在接收缓冲区中。

 

- 怎么消除业务缓冲区的累积延时呢 ?

推流端的发送缓冲区,可以在网络恢复良好的时候,快送发送出去,从而消除掉这个累积延时。

播放端的接收缓冲区,可以通过丢帧或者加速播放的方式快速消费掉缓冲区中的数据,从而消除累计延时

 

2.3 协议延时

通常标准的直播协议有 RTMP,HLV,HLS 三种,一般 RTMP/HLV 协议的延时在 1~3s,HLS 协议的直播延时则会更大,注重延时的直播应用,大都会选择 RTMP/HLV 协议,这些协议均是基于 tcp 的协议,tcp 协议的多个特性导致其延时明显要高于基于 udp 的私有协议,主要有如下方面:

- 建立连接的三次握手

- ACK 机制

- 丢包重传

因此,如果想从本质上解决直播延时问题,还是要换成基于 udp 的私有协议来传输数据

 

2. 音画同步的基础概念

 

首先我们要明白一个概念,虽然人的肉眼,很容易辨别音画是否同步的,但是机器则不然,对于播放器而言,它判断一帧视频和一帧音频是否要在同一个时间渲染和播放,依靠的完全是该数据携带的时间戳信息

如果内容的生产端给音视频数据打的时间戳本身就有问题的话,播放器也往往无能为力了,因此,音画不同步问题,更多的时候,应该从生产端去排查原因

 

3. 音画不同步的问题排查 

3.1 采集源距离太远

如果音频源离麦克风距离太远,声音传播到麦克风的速度远小于画面(光速),那么,摄像头采集到画面后给出的时间戳,肯定要远小于麦克风采集到同一时刻音频给出的时间戳,因此会产生音画不同步问题。

解决方案:音频源尽可能离麦克风设备近一点。

 

3.2 采集设备内部问题

摄像头和麦克风采集音视频,在硬件上都会经过一些信号处理模块,如果处理延时不稳定的时候,则会导致输出数据的时间不稳定,从而导致应用层获取时间戳的时候产生误差,带来音画不同步问题。

解决方案:极少数硬件/机型才会有,需要根据采集参数(如采样率)做一些 Jitter 抖动的矫正。

 

3.3 时间戳没有在采集的时候获取 

如果音视频帧的时间戳不是在采集的时候获取,而是在后续的某个环节再获取,则非常大概率地会出现音视频不同步问题。

 

先举个简单的例子:

假设音频 A 和 视频 B 同时从设备中被采集出来,时间戳为:TA 和 TB,他们差值会很小,播放端收到后会认为是同一时刻的音视频数据,从而一起播放。

但是,当 音频 A 和 视频 B 分别经过某些算法处理模块后,我们 “不慎” 在处理后重新获取当前时间戳为了 TA2 和 TB2,那么,这个更新后的时间戳差值可能会非常大,导致音画不同步。

那么,一般大家会 “不慎” 在哪些地方更改了采集的时间戳呢 ?

 

- 音视频算法处理模块

比如:视频经过美颜、编码后,重新更新为了处理后的的时间戳。

- 缓冲区导致的不同步

多线程程序中,往往会在不同线程之间共享一些帧缓冲区,缓冲区会导致音视频对应关系发生变化,如果从缓冲区取数据后,抛弃掉了原有的时间戳,重新使用新的当前时间,那么,肯定会出现问题。

- 网络传输导致的不同步

由于网络的传输的延时、丢包等原因,同一时刻的音视频包不会正好同时准确到达,如果在接收到了数据后再打上当前的时间戳,则肯定也会出现不同步问题。

 

3.4 时间戳出现回退或者紊乱

曾经有遇到过一些音画不同步的流,我把它的音视频时间戳打印出来后显示如下的结果:

wKioL1ka_C6BW2NCAAIWJyjJMK0738.png

该码流的时间戳没有单调递增,而是频繁出现了回退,这样的流,会导致播放器出现频繁卡顿,因为播放器的 master 主时钟一般是单调递增的,当出现小于主时钟的视频帧后,一般会做丢弃处理,画面不更新但是音频还是在继续播放,从而导致看起来声音和画面并没有匹配上的问题。 

解决方案:排查推流端时间戳是否单调线性递增,或者排查服务端是否有对流的时间戳有过修改导致回退。

 

3.5 播放端性能问题

 

比如低端机型软解 1080P 的高清码流,会存在解码不够及时的问题,导致部分视频解码完成后,已经远慢于当前的音频时钟,只能丢弃,从而导致画面更新不及时,与正在播放的音频无法匹配上,从而产生音画不同步的现象。

解决方案:使用硬解,选择较低清的码流,增大播放缓冲,等等

 

2. 马赛克严重的问题排查

2.1 视频编码参数配置原因

视频的画质,是由它的编码质量决定的,压缩得越 “厉害”,画质损失就越多,马赛克就越严重

 

- 哪些关键因素决定了编码器的压缩质量呢 ?

编码器最重要的五个参数:画质级别、码率、帧率、GOP 大小、码控方式

 

画质级别:H.264 有四种画质级别,Baseline profile,Extended profile,Main profile,High profile,级别越高,压缩的效果越好,但算法复杂度更高,导致功耗也更高。

码率:决定了视频被压缩的程度,码率越低,丢失的信息也就越多,画质也就越差。但是,带来的好处是占用的网络带宽会比较小,容易在互联网上传输,不容易出现卡顿。

帧率:决定了视频的流畅性,帧率越高,视频越流畅,但每秒钟编码器要处理的数据量也就越大,同等码率下压缩出来的视频质量就越差(同等码率:所以一秒内的数据量是一定的,帧率越高,每帧分到的数据量越小,所以画质越差)

GOP 大小:决定了视频的延时,GOP 越小,延时就越小,但 GOP 小带来的问题是关键帧数量多,数据量变大,因此,同等码率下压缩出来的视频质量就会越差。

码控方式:一般编码器都有固定码率(CBR) 和 动态码率(VBR) 两种码控方式,前者是指码率优先,为了保证码率尽可能稳定,会主动降低画质,因此容易出现马赛克,后者是指画质优先,会优先保证画质,减少马赛克,但码率会浮动很大。

 

当然,还有一个重要的因素,就是编码器本身的实现质量,软编一般可以保证在不同手机上效果一致,而硬编则完全依赖手机所使用的硬件平台了。

 

- 推荐的编码器参数配置

一般直播场景中,考虑到手机性能和功耗,一般画质级别采用的是 Baseline profile,GOP 通常设置为 1~3s,帧率一般在 15~24 帧,而码率的配置,则需要根据推流的分辨率来决定,推荐的分辨率和码率配置关系如下图所示(来自:《Video Encoding Settings for H.264 Excellence》):

 

wKioL1kkH_2xSDg5AAGf2s2OelU644.png

总之,关于视频编码与马赛克的关系,我们只需要记住一个原则:送入编码器的数据量越大,编码压缩得越 “厉害”,丢失的图像信息也就越多,数据解码后的产生马赛克也就越 “厉害”。

 

2.2 图像尺寸原因

一般摄像头采集的图像分辨率,跟最终推流的尺寸不一定完全匹配,当摄像头采集的分辨率大于推流尺寸的时候,需要先对画面进行 “剪裁” 处理,而当摄像头采集的分辨率大于推流尺寸的时候,则需要先对画面进行 “拉伸” 处理,然后再送入编码器中编码压缩。

 

wKioL1kkIBniUvc4AABRb5s_uDE464.png

例如:小尺寸的画面(比如:640 x 480),拉伸到大的尺寸(比如:1280 x 720),则很容易会产生模糊和马赛克,这样的画面再送入编码器中编码,无论怎样配置都无法再改善已经产生的马赛克了

所以,为了降低马赛克,我们必须要保证,摄像头采集的分辨率,一定要大于最终推流的分辨率

 

2.3 客观条件原因

如果主播在光线非常暗的环境下,本身送入编码器的图像质量也不会特别好,因此,同等条件下马赛克也会相对严重些。

同样,如果拍摄的是剧烈晃动的画面,剧烈变化的画面信息量也要大很多,因此,编码的复杂度会明显增大,如果要保证码率不会浮动太大,就必然要降低输出的图像质量,从而产生马赛克现象。

如果直播应用是主打这种光线暗的场景或者剧烈运动的画面场景的话,为了降低马赛克,可以考虑适当将编码参数配置得 “高” 一点(比如:码率高一点,帧率低一点等等),留出充分的 “富余” 空间,以抵抗环境因素带来的影响。

 

2.4 关键帧丢失

还有一种马赛克现象,是由于视频流中丢失了关键帧,导致播放器解码后花屏,从现象来看有点像马赛克,但实际上跟上面讨论的不是同一个问题,我们将在后续的文章中专门讨论这个花屏问题。

分类:

技术点:

相关文章: