H.264 H.264RTP发送和接收


1.预备知识
RTP包头的格式。
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|V=2|P|X| CC |M| PT | sequencenumber |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| timestamp |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| synchronization source(SSRC)identifier |
+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
| contributingsource(CSRC)identifiers |
| 。。。。 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
图1
H.264规范中的两种重要概念: 视频编码层(VCL)和网络抽象层(NAL)
VCL包含Codec的信令处理功能;以及如转换,量化,运动补偿预测机制;以及循环过滤器。
(NAL)封装VCL编码器输出的片断到网络抽象层单元(NALunits),它适合于通过包网路传输或用
于面向包的多路复用环境,用与实际的传输。
NAL网络抽象层单元类型
所有NAL单元有一个单个NAL单元类型字节,其后跟源数据。
+---------------+
|0|1|2|3|4|5|6|7|
+-+-+-+-+-+-+-+-+
|F|NRI| Type |
+---------------+
F: 1bit
forbidden_zero_bit。H。264规范声明为0
NRI:2bits
nal_ref_idc。一般为00。00值指示NAL单元不用于帧间图像预测来重构参考图像。
Type:5bits
这是NAL单元的类型。知道这个就可以了。
2打包和解包流程
2.1单个NAL打包
0 1 2 3
01234567890123456789012345678901
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|F|NRI| type | |
+-+-+-+-+-+-+-+-+ |
| |
| Bytes2。。nofaSingleNALunit |
| |
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| :。。。OPTIONALRTPpadding |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
图2单个NAL单元包的RTP荷载格式
注:NAL单元的第一字节和RTP荷载头第一个字节重合。(这是文档原文,不知道怎么实现啊!)
对于一个原始的H。264NALU单元常由[StartCode][NALU Header][NALU Payload]
三部分组成, 其中StartCode用于标示这是一个NALU单元的开始, 必须是"000000
01" 或"000001",NALU头仅一个字节, 其后都是NALU单元内容。打包时去除"0000
01" 或"00000001" 的开始码, 把其他数据封包到RTP包即可。
例如:
有一个H.264 的NALU是这样的:[000000016742A01E23560E2F 。。。 ]
[00000001] 是四个字节的开始码,67 是NALU头, 42 开始的数据是NALU内容。封装
成RTP包将如下:
[RTPHeader] [6742A01E23560E2F]
即只要去掉4 个字节的开始码就可以了。
在接收端,RTP接收后加上[00000001] 是四个字节的开始码即可。
2.2分片打包
当一个NAL单元比较大时, 可以分到多个RTP包中发送。
FU指示字节有以下格式:
+---------------+
|0|1|2|3|4|5|6|7|
+-+-+-+-+-+-+-+-+
|F|NRI| Type |
+---------------+
FU指示字节的类型域的28,29表示FU-A和FU-B。NRI域的值必须根据分片NAL单元的NRI域的值
设置。
FU头的格式如下:
+---------------+
|0|1|2|3|4|5|6|7|
+-+-+-+-+-+-+-+-+
|S|E|R| Type |
+---------------+
图3表示FU-A的RTP荷载格式。FU-A由1字节的分片单元指示,1字节的分片单元头,和分片单元
荷载组成。
0 1 2 3
01234567890123456789012345678901
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|FUindicator | FUheader | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| |
| FUpayload |
| |
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| :。。。OPTIONALRTPpadding |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
图3. FU-A的RTP荷载格式
0 1 2 3
01234567890123456789012345678901
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|FUindicator | FUheader | DON |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-|
图4. FU-B的RTP荷载格式(多个DON)
S:1bit
当设置成1,开始位指示分片NAL单元的开始。当跟随的FU荷载不是分片NAL单元荷载的开
始,开始位设为0。
E:1 bit
当设置成1,结束位指示分片NAL单元的结束,即, 荷载的最后字节也是分片NAL单
元的最后一个字节。当跟随的
FU荷载不是分片NAL单元的最后分片,结束位设置为0。
R:1 bit
保留位必须设置为0。
Type:5 bits
Type Packet Typename Section
---------------------------------------------------------0 undefined -1-23 NALunit Single NALunitpacketperH。264 5。6
……
28 FU-A Fragmentation unit 5。8
29 FU-B Fragmentation unit 5。8
打包过程如下:
第一个FU-A 包的FU indicator 应该是:F= NALU 头中的F;NRI =NALU 头中的NRI;Type =28。
FU header 应该是:S =1;E= 0;R =0;Type =NALU 头中的Type。
实际代码:
m_indicator[0] =m_NAL[0] &0xe0;
m_indicator[0] =m_indicator[0] +0x1C;
m_header[1]= 0x80 +(m_NAL[0]&0x1f);
中间FU-A 包的FUindicator 应该是:F =NALU 头中的F;NRI= NALU 头中的NRI;Type =28。
FU header 应该是:S =0;E= 0;R =0;Type =NALU 头中的Type。
同上代码
m_header[1]= 0x60 +(m_NAL[0]&0x1f);
尾FU-A 包的FU indicator 应该是:F =NALU 头中的F;NRI = NALU 头中的NRI;Type = 28。
FU header 应该是:S =0;E= 1;R =0;Type =NALU 头中的Type。
同上代码
m_header[1]= 0x10 +(m_NAL[0]&0x1f);
RTP 解包如下:
分析分片包的前两字节:
unsigned char startBit = headerStart[1] &0x80; //|0|1|2|3|4|5|6|7|
unsigned char endBit =headerStart[1] &0x40;
1. startBit=1分片的首包
m_NAL[0] =(headerStart[0]&0xE0) + (headerStart[1]&0x1F);
重新组合NAL单元类型字节,再在NAL头字节前面加上[00000001]即得到源码。
2.分片包的中间包
直接丢掉headerStart[0] headerStart[1]
3.分片包的末包
同样直接丢掉headerStart[0] headerStart[1] ,并累计以上各包的长度,送给解码器。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值