视频帧的概念
一、视频帧
在H264协议里,图像以组(GOP,也就是一个序列)为单位进行组织,一个组是一段图像编码后的数据流,以I帧开始,到下一个I帧结束。一个组就是一段内容差异不太大的图像编码后生成的一串数据流。当运动变化比较少时,一个组可以很长,因为运动变化少就代表图像画面的内容变动很小,所以就可以编一个I帧,然后一直P帧、B帧了。当运动变化多时,可能一个序列就比较短了,比如就包含一个I帧和3、4个P帧。
1.I帧
I帧是帧组的第一帧,在一组中只有一个I帧。I帧是帧内编码帧,是一种自带全部信息的独立帧,无需参考其他图像便可独立进行解码,可以简单理解为一张静态画面。如果传输过程中I真丢失,画面最直接的影响就是会卡顿,因为后面的帧都无法正确解码,只能等待下一个GOP。
2.P帧
P帧是帧间预测编码帧,需要参考其前面的I帧或P帧才能进行编码。P帧没有完整的画面数据,只有与其前一参考帧的画面差别的数据。与I帧相比,P帧通常占用更少的数据位,但不足是,由于P帧对前面的P和I参考帧有着复杂的依耐性,因此对传输错误非常敏感,所以如果P帧丢失,画面会出现马赛克现象,因为前向参考帧错误,补齐的并不是真正运动变化后的数据。
3.B帧
B帧是双向预测编码帧,也就是B帧记录的是本帧与前后帧的差别。也就是说要解码B帧,不仅要取得之前的缓存画面,还要解码之后的画面,通过前后画面的与本帧数据的叠加取得最终的画面。B帧压缩率高,但解码时很耗CPU资源。(B帧以前面的I或P帧和后面的P帧为参考帧,B帧不是参考帧,不会造成解码错误的扩散。)
一般来说,I帧的压缩率是7(跟JPG差不多),P帧是20,B帧可以达到50。虽然B帧压缩率高,但是在直播系统中很少使用B帧,一是因为解码很耗CPU,再就是B帧解码需要等待下一个P帧数据,这就会造成解码延时,而直播系统对延时要求很高,所以一般不用B帧。但对于点播系统就不会有这个问题。
二、PTS和DTS
PTS(Presentation TimeStamp)是渲染用的时间戳,也就是说,我们的视频帧是按照 PTS 的时间戳来展示的。DTS(Decoding TimeStamp)解码时间戳,是用于视频解码的。
为什么会有2个不同的时间戳呢?这和I帧、P帧和B帧有关,我们分2中情况来看:
1.视频中只有I帧和P帧
如下所示,第1帧是I帧,2-8帧是P帧,展示的顺序是12345678。解码时先解码第1帧,第2帧参考第1帧解码,第3帧参考第2帧解码……也就是解码顺序也是12345678。这种情况下PTS和DTS是一样的,所以此时是没有必要区分2个不同的时间戳的。
1 2 3 4 5 6 7 8
I P P P P P P P
2.视频中有I帧、P帧和B帧时
如下所示,第1帧是I帧,第4、8帧是P帧,其余是B帧,展示顺序是12345678。解码时先解第1帧,第2帧是B帧,由于它后面的帧还没解码,所以它也没法解码,第3帧也是一样,所以第二解码是第4号的P帧,然后2号B帧参考其前面的第1帧和其后面的第4帧进行解码,然后再是3号B帧解码,然后567号B帧要等到8号的P帧解码后才能解码。所以解码的顺序是14238567,这种情况下展示顺序和解码顺序就不一样,所以就有了PTS和DTS的区分。
1 2 3 4 5 6 7 8
I B B P B B B P