H264 码流格式

H264 的两种码流格式,它们分别为:字节流格式RTP包格式

  • 字节流格式: 默认的输出格式。它的基本数据单位为 NAL 单元,也即 NALU。为了从字节流中提取出 NALU,协议规定,在每个 NALU 的前面加上起始码:0x000001 或 0x00000001(0x 代表十六进制)
  • RTP 包格式:一种数据传输格式,主要用于网络传送

字节流格式,由于它没有经过传输协议封装,所以也可以称之为裸流

1
H264比特流 = Start_Code_Prefix + NALU + Start_Code_Prefix + NALU + ...

H264_struct

起始码与 NALU

起始码(Start_Code_Prefix): 0x00 00 010x00 00 00 01

在两个起始码之间的数据,称为 NALU

NALU

NAL Unit: Network Abstract Layer Unit

每个 NAL 单元包括一个原始字节序列负荷 (RBSP, Raw Byte Sequence Payload)、一组对应于视频编码的 NAL 头信息

1
NALU = NALU Header + RBSP
  • SODB: 最原始的编码数据,无任何附加数据。
    • String Of Data Bits
  • RBSP: 在 SODB 的基础上增加了 rbsp_stop_ont_bit (bit 值为 1) 并用 0 按字节补位对齐。
    • A NALU contains a Raw Byte Sequence Payload, a sequence of bytes containing syntax elements.
  • EBSP:(Encapsulation Byte Sequence Packets) 在 RBSP 的基础上增加了防止伪起始码字节 (0x03)。

NALU Header

1
2
NAL Header: forbidden_bit, nal_reference_bit(优先级), nal_unit_type(类型)
1bit 2bit 5bit

SPS (Seq_Parameter_Set) – 序列参数集

H.264 码流第一个 NALU 是 SPS

nal_unit_type = 7, 包含 H.264 的 profile_idclevel_idc 等信息。还有图像的宽高:pic_width_in_mbs_minus1pic_height_in_map_units_minus1

图像的宽和高,以宏块(16x16)为单位的值减 1, 如果 pic_width_in_mbs_minus1 = 21, 图像宽为(21+1)* 16 = 352

SPS 即 Sequence Paramater Set,又称作序列参数集。SPS 中保存了一组编码视频序列(Coded video sequence) 的全局参数。所谓的编码视频序列即原始视频的一帧一帧的像素数据经过编码之后的结构组成的序列。而每一帧的编码后数据所依赖的参数保存于图像参数集中。

PPS (Pic_Parameter_Set) – 图像参数集

H.264 码流第二个 NALU 是 PPS

nal_unit_type = 8

Slice

一个视频图像可编码成一个或更多个条带,每个条带包含整数个宏块(MB),即每个条带至少一个 MB,最多时每个条带包含整个图像的宏块。总之,一幅图像中每个条带的宏块数不一定固定。设条带的目的是为了限制误码的扩散和传输,应使编码条带相互间是独立的。某个条带的预测不能以其它条带中的宏块为参考图像,这样某一条带中的预测误差才不会传播到其它条带中去。

Tile

GOP

在视频编码序列中,GOP 即 Group of picture(图像组),指两个I帧之间的距离Reference(参考周期)指两个P帧之间的距离。一个 I 帧所占用的字节数大于一个 P 帧,一个 P 帧所占用的字节数大于一个 B 帧。

H264_GOP

GOP 说白了就是两个 I帧之间的间隔。比较说 GOP 为 120, 如果是 720p60 的话,那就是 2s 一次 I 帧

视频渐近刷新

视频渐近刷新 GDR(Gradual decoder refresh) 是相对一帧完整刷新而来。传统 IDR (Instantaneous Decoding Refresh: 即时解码刷新) 刷新的缺点是 IDR 帧大小相比图像质量相近的 P 帧更大,这样会对网络有冲击,导致网络抖动和拥塞。而 GDR 会带来更优的网络适应性。
GDR 是通过 P帧内包括 I帧块组的方法来实现渐近刷新。

h264 GDR

参考