视频编码基础

视频传输基本原理

视频是利用人眼的视觉暂留的原理,通过播放一系列的图片,使人眼产生运动的感觉。单纯传输视频画面,视频量非常大,对现有的网络和存储来说很不友好。为了能够使视频便于传输和存储,人们发现有视频有大量重复的信息,如果将重复信息在发送端去掉,在接收端回复回来,这样就大大减少了视频数据的文件,因此有了H.264视频压缩标准。

视频里面最常用的编码格式就说H.264,基于这个编码格式还有H.265(后续研究),音频采样数据会采用AAC编码格式进行压缩。视频内容经过编码压缩后,确实有利于存储和传输。不过当要观看播放视频时,相应也需要解码过程,将压缩的视频还原。所以,编解码之间显然需要约定一种协议,这种协议大概的流程是:编码器将多张图像进行编码后产生一段一段的GOP(Group of picture),解码器则在播放时读取一段一段的GOP进行解码后读取画面再渲染显示。

1.png

GOP是一组连续的画面,由一张I帧和数张B帧和P帧组成,它是视频图像编码器和解码器存取的基本单位,它的排列顺序将会一直重复到影像结束。I帧是内部编码帧(也称为关键帧),P帧是前向预测帧(前向参考帧),B帧是双向内插帧(双向参考帧)。简单说,I帧是一个完整的画面,而P帧和B帧记录的是相对于I帧的变化。如果没有I帧,P和B是无法解码的。

在H.264编码中I帧,P帧,B帧传输的视频画面

I帧,P帧,B帧

  • I帧
    I帧:即Intra-coded picture(帧内编码图像帧),I帧表示关键帧,你可以理解为这一帧画面的完整保留;每个GOP组中第一帧一定是I帧,而且是一种特殊的I帧,也可以称为IDR帧,一个GOP可以有很多I帧,但是只有1个IDR帧。I帧法是基于离散余弦变换DCT(Discrete Cosine Transform)的压缩技术,这种算法与JPEG压缩算法类似。采用I帧压缩可达到1/6的压缩比而无明显的压缩痕迹。
    2.png

I帧的特点:

  1. 它是一个全帧压缩编码帧。它将全帧图像信息进行JPEG压缩编码及传输
  2. 解码时仅用I帧的数据就可以重构完整的图像
  3. I帧描述了图像背景和运动主体的详情
  4. I帧不需要参考其他画面而生成
  5. I帧是P帧和B帧的参考帧
  6. I帧所占数据的信息量比较大
  • P帧
    P帧:即Predictive-coded Picture(前向预测编码图像帧)。P帧表示的是这一帧跟之前的一个关键帧(或P帧)的差别,解码时需要用之前缓存的画面叠加上本帧定义的差别,生成最终画面。(也就是差别帧,P帧没有完整画面数据,只有与前一帧的画面差别的数据)
    3.png

P帧的特点:

  1. P帧是I帧后面相隔1-2帧的编码帧
  2. P帧采用运动补偿的方法传送它与前面的I或者P帧的差值及运动矢量预测误差
  3. 解码时必须将I帧中的预测值与预测误差求和后才能重构完整的P帧图像
  4. P帧属于前向预测的帧间编码。它只参考前面最靠近它的I帧或P帧
  5. P帧可以是其后面P帧的参考帧,也可以是其前后的B帧的参考帧
  6. 由于P帧是参考帧,它可能造成解码错误的扩散
  7. 由于是差值传输,P帧的压缩比较高(大概I帧的一半大小)
  • B帧
    B帧:即Bidirectionally predicted picture(双向预测编码图像帧)。B帧是双向差别帧,也就是B帧记录的是本帧与前后帧的差别,换言之,要解码B帧,不仅要取得之前的缓存画面,还要解码之后的画面,通过前后画面的与本帧数据的叠加取得最终的画面。B帧压缩率高,但是解码时CPU会比较累。
    4.png

B帧的特点

  1. B帧是由前面的I或P帧和后面的P帧来进行预测的
  2. B帧传送的是它与前面的I帧或者P帧和后面的P帧之间的预测误差及运动矢量
  3. B帧是双向预测编码帧
  4. B帧压缩比最高,对解码性能要求也高(大概I帧的四分之一)
  5. 需要参考前一个I帧或者P帧及其后面的一个P帧来生成一张完整的视频画面,所以P帧与B帧去掉的是视频帧在时间维度上的冗余信息。

B帧存在的价值
从上面分析可知,I帧和P帧的解码算法比较简单,资源占用比较少,I只要自己完成就行了,P帧也只需要解码器把前一个画面缓存一下,遇到P时就使用之前缓存的画面就好了,如果只有I和P,解码器可以不用处理后续数据,边读边解码,那为什么还要引入B帧呢?因为B帧记录了前后帧的差别,比P帧能节约更多空间,这样视频文件可以变小,但是相应的就要求解码器性能比较高了,因为在解码时,不仅要用之前缓存的画面,还要知道下一个I或者P的画面(也就时说要预读,预解码),而且,B帧不能简单丢掉,因为B帧其实也包含了画面信息,如果简单丢掉,并用之前的缓慢简单重复,就会造成画面卡顿(丢帧)。