音视频学习之 - H264结构与码流解析

3,908 阅读4分钟

H264结构图:

image.png

H264视频压缩后会成为一个序列帧,帧里包含图像,图像分为很多片,每个片可以分为宏块,每个宏块由许多子块组成 H264结构中,一个视频图像编码后的数据叫做一帧,一帧由一个片(slice)或多个片组成,一个片由一个或多个宏块(MB)组成,一个宏块由16x16的yuv数据组成。宏块作为H264编码的基本单位。

  • 场和帧:视频的一场或者一帧可以用来产生一个编码图像。在电视中,每个电视帧都是通过扫描屏幕两次而产生的,第二个扫描的线条刚好填满第一次扫描所留下的缝隙。每个扫描即称为一个场。因此 30 帧/秒的电视画面实际上为 60 场/秒
  • :每个图像中,若干个宏块被排列成片。片的目的:为了限制误码的扩散和传输,使编码片相互间保持独立。片共有5种类型:I片(只包含I宏块)、P片(P和I宏块)、B片(B和I宏块)、SP片(用于不同编码流之间的切换)和SI片(特殊类型的编码宏块)。
  • 宏块:一个编码图像首先要划分成多个块(4x4 像素)才能进行处理,显然宏块应该是整数个块组成,通常宏块大小为16x16个像素。宏块分为I、P、B宏块,I宏块只能利用当前片中已解码的像素作为参考进行帧内预测;P宏块可以利用前面已解码的图像作为参考图像进行帧内预测;B宏块则是利用前后向的参考图形进行帧内预测

H264编码分层

  • NAL层:(Network Abstraction Layer,视频数据网络抽象层): 它的作用是H264只要在网络上传输,在传输的过程每个包以太网是1500字节,而H264的帧往往会大于1500字节,所以要进行拆包,将一个帧拆成多个包进行传输,所有的拆包或者组包都是通过NAL层去处理的。
  • VCL层:(Video Coding Layer,视频数据编码层): 对视频原始数据进行压缩

码流的基本概念

  • SODB:(String of Data Bits,原始数据比特流):由VCL层产生,数据长度不一定是8的倍数,所以处理起来比较麻烦
  • RBSP:(Raw Byte Sequence Payload,SODB+trailing bits,编码后的数据流):算法是在SODB最后一位补1,不按字节对齐补0,如果补齐0,不知道在哪里结束,所以补1,如果不够8位则按位补0
  • EBSP:(Encapsulate Byte Sequence Payload):生成编码后的数据流之后,我们还要在每个帧之前加一个起始位,需要开发者人为添加。起始位一般是十六进制的0001。但是在整个编码后的数据里,可能会出来连续的2个0x00。那这样就与起始位产生了冲突.那怎么处理了? H264规范里说明如果处理2个连续的0x00,就额外增加一个0x03 。这样就能预防压缩后的数据与起始位产生冲突
  • NALU: (NAL Header(1B)+EBSP).NALU就是在EBSP的基础上加1B的网络头.

NALU解析

image.png

  • NALU头结构:NALU类型(5bit)、重要性指示位(2bit)、禁止位(1bit):第1位为禁位,默认固定为0,如果接收到的为1,那么就需要丢弃该单元;第2-3位表示重要性,00表示最不重要,11表示最重要,我们可以在解码来不及的情况下舍弃一些不重要的单元;第4-8位用来表示NALU的类型

  • NALU类型:1~12由H.264使用,24~31由H.264以外的应用使用:类型图如下:

    image.png

  • 切片与宏块的关系:每个切片包括切片头和切片数据,每个切片数据包括了很多宏块。每个宏块包括了宏块类型、宏块预测、残差效果:

    image.png

  • 切片头:包含了一组片的信息,比如片的数量,顺序等等

H264码流分层结构图

image.png