视频云直播中的关键帧技术探秘
2016-11-26
迅达云SpeedyCloud工程副总裁,2010年始涉足云计算行业,至今积累了大量架构、研发、运维、运营、管理等经验,曾就职于Joyent、蓝汛、Yottaa等公司。2013年加入SpeedyCloud迅达云,现在负责技术的总体把控、技术可行性调研等工作。
关键帧的痛点
在视频领域,电影、电视、数字视频等可视为随时间连续变换的许多张画面,而帧则指这些画面当中的每一张。不过如果按照如此的方式存储视频的话,文件势必会变得很大,所以需要专门的算法对视频文件进行编码。一旦视频进行编码之后,得到的文件可以看做是连续的一组帧的集合,而这一组帧中的每一个都是有自己的类型的。帧的类型分为以下3种:
*Inter Frame(I帧)
*P-Frame(P帧)
*B-Frame(B帧)
对于B帧和P帧来说需找到对应的一个或者多个参考帧才能解码出来(如图1)。
对于非I帧来说想要进行解码就需要多个参考帧进行计算,由此引出了Groupof Picture(以下简称GoP)的概念。
对于P帧和B帧来说,他们所包含的内容可以理解为针对其参考帧的一个patch,也就是一个变化量。
GoP性能调优分析
GoP顾名思义就是有一组帧组成的一个序列。Wikipedia上给出的一个图简单的解释了GoP是怎么回事(如图 2)。
GoP由I帧开始,后面跟随者一组B帧和P帧,直到下一个I帧之前的帧为一个GoP。了解了GoP之后,就会发现播放器只有在拿到某个GoP中的I帧之后才能播放视频。
图1 B帧和P帧对应多个参考帧
GoP到底应该设置多大?那么GoP的大小到底有什么影响呢?
GoP设置较大时:
好处:由于B帧和P帧的字节大小会比I帧小很多,所以GoP越长,所包含的B帧和P帧越多,相应的压缩比也会更高,在同样的码率下,视频会更清晰一些。
坏处:对于视频直播来说,播放器连接到服务器的时间是不固定的,当播放器在GoP中间连接服务器,并获取了中间的B帧和P帧,这时播放器是无法对这些帧进行解码的,需要进行丢弃。所以会导致客户端的首屏播放时间变长。
GoP设置较小时:
好处:由于GoP设置小可以降低I帧间隔时间,对于直播来说可以实现秒开的功能。
坏处:由于GoP时间比较短,会导致I帧的比例增高,压缩比降低。同样码率情况下视频的质量会有所下降。
为什么HLS视频加载会慢?
HLS格式的视频分为两个部分。首先,HLS会根据指定的切片时间和实际的GoP大小对视频进行切割,并生成.ts文件。其次,HLS会生成一个.m3u8文件来保存这些ts文件的索引。
对于.ts文件的切割来讲,并不是告诉直播服务器指定1秒切一个.ts文件他就能保证1秒切一个.ts文件的。.ts文件的切割还是要根据直播视频的实际GoP大小来进行切割的。之前已经讲过,任何一个视频流在播放端需要能获取到完整的GoP才能播放,所以一个.ts文件所实际包含的时间是GoP的整数倍。
例如:当视频的GoP设置为1秒,.ts切片时间为2秒时,实际的.ts文件切片所包含的视频为2秒。当视频的GoP设置为5秒,.ts切片时间为2妙时,实际的.ts文件切片所包含的视频为5秒。
图 2 GoP示意图
如果视频流的GoP大小设置不合适的话,那么HLS的切片时间就会变长,同时也会增加HLS的延迟。这个特性对于HLS直播来讲简直就是延迟杀手。
如果是HLS点播的话,流的GoP设置过大也会影响点播视频的加载时间。一般的一个720P的视频,如果切片时间为2秒的话,单个.ts文件也就是在百K字节上下。但如果源视频的GoP很大,会导致第一个.ts文件所包含的视频时常变长(比如10秒),同时导致.ts文件的大小膨胀到接近1M字节上下。
为什么RTMP直播首屏渲染速度很慢?
RTMP协议本身也会抽象出一个Packet的概念来封装H264编码中的帧,也就是一个Packet会包含1到多个帧,播放器以Packet为单位来进行解码。那么RTMP的问题在于客户端连接的时间点是否合适。
例如一个RTMP直播流的GoP设置为2秒,如果客户端接入时间刚好是第4秒,那么客户端会获取一个包含I帧的Packet,由于I帧是自描述的,所以客户端可以直接解码出该帧的画面并显示出来。但是当客户端的接入之间为第5秒,那么他会获得一个包含B帧或者P帧的Packet,由于客户端拿到的数据是一个不完整的GoP,所以客户端只好抛弃当前获取的Packet中视频的数据,而且只有当获取到包含下一个GoP的I帧的Packet时才能解码出图像。因此客户端会等待1秒才能播放出画面。
由此我们可以得出一个结论:GoP的大小会影响RTMP播放端的首帧加载时间。
为了优化首帧加载时间,我们可以在流媒体服务器端增加一个缓存,把上一个GoP缓存在内存中。如果客户端接入的话,我们首先放出来的是上一个GoP。这样客户端接到的数据永远是一I帧开头的数据。
结论
在视频直播和点播盛行的年代,对于GoP大小的取舍还是需要看具体应用场景。对于直播来讲,对延迟要求敏感的应用来说,1~2秒的GoP大小还是比较合适的,至于GoP缓存来讲,还是不用为好。如果是对延迟要求不敏感,对首屏播放时间很敏感的应用,GoP还是1~2秒最为合适,GoP缓存应该是必备的。另外直播使用HLS的话,延迟是绝对PK不过RTMP的。
对于点播的应用来说,视频加载速度是个硬指标,如果不是HLS格式的话,GoP大小适当选大一点可以降低视频文件大小,提高视频打开速度。
HLS格式的话,还是推荐在2秒左右,否则很影响视频打开速度的。
其实视频直播技术的挑战很多,这次分享的只是其中一小部分,也是迅达云SpeedyCloud研发团队的经验总结,希望能够和大家多交流,一起为技术社区发展做些有益的事情。