首页交流分享RTP H264组包之单个NAL包和FU-A方式解析

RTP H264组包之单个NAL包和FU-A方式解析

时间2015-09-11 09:04:11发布caterwang分类交流分享浏览11356

    为了在HI3615上调试RTSP,在网络上搜索整理的资料,因为调试时只用到了单个NAL包和FU-A方式,所以只摘抄了这两种方式的说明。特此分享。

    1.RTP Header 解析blob.png

                                                   图1

    1)V: RTP 协议的版本号,占 2 位,当前协议版本号为 2

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

    3)X:扩展标志,占 1 位,如果 X=1,则在 RTP 报头后跟有一个扩展报头

    4)CC: CSRC 计数器,占 4 位,指示 CSRC 标识符的个数

    5)M: 标记,占 1 位,不同的有效载荷有不同的含义,对于视频,标记一帧的结束;对于音频,标记会话的开始。

    6)PT: 有效荷载类型,占 7 位,用于说明 RTP 报文中有效载荷的类型,如 GSM 音频、 JPEM 图像等, 在流媒体中大部分是用来区分音频流和视频流的,这样便于客户端进行解析。

    7) 序列号: 占 16 位, 用于标识发送者所发送的 RTP 报文的序列号, 每发送一个报文, 序列号增 1。 这个字段当下层的承载协议用 UDP 的时候, 网络状况不好的时候可以用来检查丢包。 同时出现网络抖动的情况可以用来对数据进行重新排序,序列号的初始值是随机的,同时音频包和视频包的 sequence是分别记数的。

    8) 时戳(Timestamp) :占 32 位,必须使用 90 kHz 时钟频率。时戳反映了该 RTP 报文的第一个八位组的采样时刻。接收者使用时戳来计算延迟和延迟抖动,并进行同步控制。

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

    10) 特约信源(CSRC) 标识符: 每个 CSRC 标识符占 32 位, 可以有 0~15 个。 每个 CSRC 标识了包含在该

    RTP 报文有效载荷中的所有特约信源。

    注:基本的 RTP 说明并不定义任何头扩展本身,如果遇到 X=1,需要特殊处理

    取一段码流如下:

    80 e0 00 1e 00 00 d2 f0 00 00 00 00 41 9b 6b 49 € ?....??....A?kI

    e1 0f 26 53 02 1a ff06 59 97 1d d2 2e 8c 50 01 ?.&S....Y?.?.?P.

    cc 13 ec 52 77 4e e50e 7b fd 16 11 66 27 7c b4 ?.?RwN?.{?..f'|?

    f6 e1 29 d5 d6 a4 ef3e 12 d8 fd 6c 97 51 e7 e9 ??)????>.??l?Q??

    cfc7 5e c8 a9 51 f6 82 65 d6 48 5a 86 b0 e0 8c ??^??Q??e?HZ????

    其中,

    80 是 V_P_X_CC

    e0 是 M_PT

    00 1e 是 SequenceNum

    00 00 d2 f0 是 Timestamp

    00 00 00 00 是 SSRC

    把前两字节换成二进制如下

    1000 0000 1110 0000

    按顺序解释如下:

    10 是 V;

    0 是 P;

    0 是 X;

    0000 是 CC;

    1 是 M;

    110 0000 是 PT;

    2.RTP 荷载 H264 码流

blob.png

                                                                            图2

    荷载格式定义三个不同的基本荷载结构, 接收者可以通过 RTP 荷载的第一个字节后 5 位(如上图)识别荷载结构。

    1) 单个 NAL 单元包:荷载中只包含一个 NAL 单元。 NAL 头类型域等于原始 NAL 单元类型, 即在范围 1到 23 之间;

    2) 聚合包:本类型用于聚合多个 NAL 单元到单个 RTP 荷载中。本包有四种版本, 单时间聚合包类型 A(STAP-A) ,单时间聚合包类型 B (STAP-B) ,多时间聚合包类型(MTAP)16 位位移(MTAP16), 多时间聚合包类型(MTAP)24 位位移(MTAP24) 。赋予 STAP-A, STAP-B, MTAP16, MTAP24 的 NAL 单元类型号分别是 24,25, 26, 27;

    3) 分片单元: 用于分片单个 NAL 单元到多个 RTP 包。 现存两个版本 FU-A, FU-B, 用 NAL 单元类型 28,29 标识;

    常用的打包时的分包规则是:如果小于 MTU 采用单个 NAL 单元包,如果大于 MTU 就采用 FUs 分片方式。

    因为常用的打包方式就是单个 NAL 包和 FU-A 方式,所以我们只解析这两种。

    2.1.单个 NAL 单元包

blob.png

                                                                       图3

定义在此的 NAL 单元包必须只包含一个。这意味聚合包和分片单元不可以用在单个 NAL 单元包中。并且 RTP 序号必须符合 NAL 单元的解码顺序。 NAL 单元的第一字节和 RTP 荷载头第一个字节重合。如图 3。打包 H264 码流时,只需在帧前面加上 12 字节的 RTP 头即可。

2.2.分片单元(FU-A)

blob.png

                                                                    图4

    分片只定义于单个 NAL 单元不用于任何聚合包。 NAL 单元的一个分片由整数个连续 NAL 单元字节组成。 每个 NAL 单元字节必须正好是该 NAL 单元一个分片的一部分。 相同 NAL 单元的分片必须使用递增的 RTP 序号连续顺序发送(第一和最后分片之间没有其他的 RTP 包) 。 相似, NAL 单元必须按照 RTP顺序号的顺序装配。

    当一个 NAL 单元被分片运送在分片单元(FUs) 中时,被引用为分片 NAL 单元。 STAPs,MTAPs 不可以被分片。 FUs 不可以嵌套。 即, 一个 FU 不可以包含另一个 FU。 运送 FU 的 RTP 时戳被设置成分片NAL 单元的 NALU 时刻。

    图 4 表示 FU-A 的 RTP 荷载格式。 FU-A 由 1 字节的分片单元指示(如图 5) , 1 字节的分片单元头(如图 6),和分片单元荷载组成。

blob.png

                       图5                                                                                                            图6

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

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

    R: 1 bit 保留位必须设置为 0,接收者必须忽略该位打包时,原始的 NAL 头的前三位为 FU indicator 的前三位,原始的 NAL 头的后五位为 FU header 的后五位。

    取一段码流分析如下:

    80 60 01 0f 00 0e 10 00 00 0000 00 7c 85 88 82 € `..........|???

    00 0a 7f ca 94 05 3b7f 3e 7f fe 14 2b 27 26 f8 ...??.;.>.?.+'&?

    89 88 dd 85 62 e1 6dfc 33 01 38 1a 10 35 f2 14 ????b?m?3.8..5?.

    84 6e 21 24 8f 72 62f0 51 7e 10 5f 0d 42 71 12 ?n!$?rb?Q~._.Bq.

    17 65 62 a1 f1 44 dc df 4b 4a 38 aa 96 b7 dd 24 .eb??D??KJ8????$ 前 12 字节是 RTP Header

    7c 是 FU indicator

    85 是 FU Header

    FU indicator(0x7C)和 FU Header(0x85)换成二进制如下

    0111 1100 1000 0101

    按顺序解析如下:

    0 是 F

    11 是 NRI

    11100 是 FU Type,这里是 28,即 FU-A

    1 是 S, Start,说明是分片的第一包

    0 是 E, End,如果是分片的最后一包,设置为 1,这里不是

    0 是 R, Remain,保留位,总是 0

    00101 是 NAl Type,这里是 5,说明是关键帧(不知道为什么是关键帧请自行谷歌)

    打包时, FUindicator 的 F、 NRI 是 NAL Header 中的 F、 NRI, Type 是 28; FU Header 的 S、 E、 R

    分别按照分片起始位置设置, Type 是 NAL Header 中的 Type。

    解包时,取 FU indicator 的前三位和 FU Header 的后五位,即 0110 0101(0x65)为 NAL 类型。

    原内容出处:http://blog.csdn.net/chen495810242/article/details/39207305

凯特网版权声明:以上内容允许转载,但请注明出处,谢谢!

展开全文READ MORE
H264RTP视频RTSP单个NAL包FU-A
[TI官方]US2.0电路板设计及布线指南摘录 智能超声波洁牙机的设计

游客 回复需填写必要信息