网络知识 娱乐 H264码流格式

H264码流格式

简介

H264码流格式有多种打包格式,包括字节流格式和RTP格式。本文详细介绍这几种码流格式。

字节流格式之AnnexB

AnnexB格式

字节流格式是h264官方协议文档中规定的格式,大部分编译器都支持这种格式的输出。AnnexB格式主要用于实时媒体网络数据传输,会在发送每个关键帧(I 帧)之前发送SPS和PPS数据,接收端可以随机解码并播放。

2.2 协议结构

协议规定,在每个NALU的前面加上起始码:0x000001或0x00000001。

基本格式如下:Start Code + NALU

  • 当起始码是0x00000001时,每个完整数据帧NAL单元或SPS数据NAL单元,或PPS数据NAL单元前都会添加上起始码,即0x00000001是每个NALU之间的间隔码,如下:
H264码流格式

  • 当起始码是0x000001时,完整数据帧会分片成多个Slice,每个Slice前都会添加上起始码,即0x000001是Slice之间的间隔码,如下:
H264码流格式

字节流格式之AVCC

3.1 AVCC格式

AVCC格式相较于AnnexB格式,无需起始码,可以减少资源浪费。通常用于存储媒体文件到硬盘上,如MP4,MKV封装格式。

3.2 协议结构

协议规定,在每个NALU前加上NALU的长度值,长度值的字节可以是1,2,4字节,大端格式,具体长度占用字节数在头部信息里指明。

基本格式如下:NALU Lengh + NALU

  • 当AVCC格式表示前缀信息时,如下所示:
H264码流格式

FFmpeg截取MP4文件头部信息,如下所示:

01 64 00 28 FF E1 00 18 67 64 00 28 AC 24 88 07 88 22 7E 58 40 00 00 FA 40 00 3A 98 03 C6 8C AB 01 00 04 68 EE 3C B0

头部信息字段表示如下:

字节序号

值(十六进制)

说明

1

0x01

Configuration version,默认0x01。

2

0x64

这是提取来自SPS的字段值,表示编码级别。

3

0x00

Profile compatibility。

4

0x28

AVC Level Indication,提取来自SPS的字段值,表示编码能力,跟分辨率、帧率、码率有关系。

5

0xFF

字节最后两位表示NALU长度占用字节数,即字节最后两位数值加1,这里是3+1=4字节。

6

0xE1

保留。

7, 8

0x00, 0x18

SPS数据长度,这里长度是24字节。

9-32

0x67-0xAB

SPS NALU数据。

33

0x01

PPS个数。

33, 34

0x00, 0x04

PPS数据长度,这里长度是4字节。

35-38

0x68-0xB0

PPS NALU数据。

  • 当AVCC格式表示媒体数据时,如下所示:
H264码流格式

RTP格式

4.1 RTP格式

实时流协议RTSP主要是对流媒体提供诸如播放、暂停、快进等操作,本身不具备传输媒体数据,需要RTP数据协议负责对流媒体数据进行封包并实现媒体流的实时传输,需要RTCP协议实时监控数据传输质量,为系统提供拥塞控制和流控制,使得实时流媒体数据的受控和点播变得可能。

4.2 协议结构

协议规定,在每个RTP数据报由头部信息和负载数据组成,其中头部前12个字节的含义是固定的,而负载则可以是音频或者视频数据。

基本格式如下:RTSP Header + RTP Header + Payload

  • RTP 头部字段表示如下:

字节序号

值(字符)

位宽

说明

1

V

2bit

RTP协议的版本号。

P

1bit

填充标志,如果P=1,则在该报文的尾部填充一个或多个额外的八位组,它们不是有效载荷的一部分。

X

1bit

扩展标志,如果X=1,则在RTP报头后跟有一个扩展报头。

CC

4bit

CSRC计数器。

2

M

1bit

不同的有效载荷有不同的含义。对于视频,标记一帧的结束;对于音频,标记会话的开始。

PT

7bit

有效荷载类型,0x60表示视频数据类型,0x61表示音频数据类型。

3,4

Sequence

2Byte

用于标识发送者所发送的RTP报文的序列号,每发送一个报文,序列号增1。

5,6,7,8

Timestamp

4Byte

时间戳

9,10,11,12

SSRC

4Byte

用于标识同步信源。该标识符是随机选择的,参加同一视频会议的两个同步信源不能有相同的SSRC。

RTSP头部字段表示如下:

字节序号

位宽

说明

1

1Byte

固定字符为'$'。

2

1Byte

RTP的通道号,0x00表示视频数据,0x01表示音频数据。

3,4

2Byte

RTP长度,包括RTP头字节和负载数据,大端格式。

  • 当负载数据不分片时,如下所示:
H264码流格式

Payload数据如果有起始码(00 00 00 01),需要先去掉。Payload首字节即可为RTP负载的首字节,所以RTSP Header里字节长度为12字节的RTP 头部和Payload数据长度。

  • 当负载数据分片时,如下所示:
H264码流格式

FU Indicator 分片指示器字段表示如下:

字节序号

字段名

位宽

说明

1

F

1bit

禁止位,协议规定为0。

NRI

2bit

重要性指示位,取值范围0~3。值越大,代表NALU越重要,就需要优先被保护。

Type

5bit

分片指示,默认为28。

FU header 分片单元头字段表示如下:

字节序号

字段名

位宽

说明

1

S

1bit

当设置成 1, 开始位指示分片 NAL 单元的开始。当跟随的荷载不是分片 NAL 单元荷载的开始,开始位设为 0。

E

1bit

当设置成 1, 结束位指示分片 NAL 单元的结束,即, 荷载的最后字节也是分片 NAL 单元的最后一个字节。当跟随的荷载不是分片 NAL 单元的最后分片, 结束位设置为 0。

R

1bit

保留位必须设置为 0。

NAL Type

5bit

取NALU的nal_unit_type。

由于分片头需要用到负载数据首字节的类型数据,所以Payload首字节提取出来,后面的数据用于分片。RTSP Header里字节长度为12字节的RTP 头部,2字节的分片头长度,和Payload数据分片长度。