FU-A拆包方式小议
来源:互联网 发布:金山软件2017业绩 编辑:程序博客网 时间:2024/05/07 16:30
RFC3984是H.264的baseline码流在RTP方式下传输的规范,这里只讨论FU-A分包方式。
1、单个NAL包单元
一个封装单个NAL单元包到RTP的NAL单元流的RTP序号必须符合NAL单元的解码顺序。单个NAL单元包的结构显示在图1。
注: NAL单元的第一字节和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
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|F|NRI| type | |
+-+-+-+-+-+-+ |
| |
| Bytes 2..n of a Single NAL unit |
| |
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
| :...OPTIONAL RTP padding |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
图1. 单个NAL单元包的RTP荷载格式。
2、FU-A的分片格式
如图2所示,FU-A的RTP荷载格式。FU-A由1字节的分片单元指示,1字节的分片单元头,和分片单元荷载组成。
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
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| FU indicator| FU header | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-++-++-++-++-++-++-++-++-++-++-+|
| |
| FU payload |
| |
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| :...OPTIONAL RTP padding |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
图 2. FU-A的RTP荷载格式
FU indicator有以下格式:
+---------------+
|0|1|2|3|4|5|6|7|
+-+-+-+-+-+-+-+-+
|F|NRI| Type |
+---------------+
FU指示字节的类型域,28表示FU-A。。NRI域的值必须根据分片NAL单元的NRI域的值设置。
FU header的格式如下:
+---------------+
|0|1|2|3|4|5|6|7|
+-+-+-+-+-+-+-+-+
|S|E|R| Type |
+---------------+
S: 1 bit
当设置成1,开始位指示分片NAL单元的开始。当跟随的FU荷载不是分片NAL单元荷载的开始,开始位设为0。
E: 1 bit
当设置成1, 结束位指示分片NAL单元的结束,即, 荷载的最后字节也是分片NAL单元的最后一个字节。当跟随的FU荷载不是分片NAL单元的最后分片,结束位设置为0。
R: 1 bit
保留位必须设置为0,接收者必须忽略该位。
Type: 5 bits
NAL单元荷载类型定义见下表
表1. 单元类型以及荷载结构总结
Type Packet Type name
---------------------------------------------------------
0 undefined -
1-23 NAL unit Single NAL unit packet per H.264
24 STAP-A Single-time aggregation packet
25 STAP-B Single-time aggregation packet
26 MTAP16 Multi-time aggregation packet
27 MTAP24 Multi-time aggregation packet
28 FU-A Fragmentation unit
29 FU-B Fragmentation unit
30-31 undefined -
3、拆包和解包
拆包:当编码器在编码时需要将原有一个NAL按照FU-A进行分片,原有的NAL的单元头与分片后的FU-A的单元头有如下关系:
原始的NAL头的前三位为FU indicator的前三位,原始的NAL头的后五位为FU header的后五位,FU indicator与FU header的剩余位数根据实际情况决定。
解包:当接收端收到FU-A的分片数据,需要将所有的分片包组合还原成原始的NAl包时,FU-A的单元头与还原后的NAL的关系如下:
还原后的NAL头的八位是由FU indicator的前三位加FU header的后五位组成,即:
nal_unit_type = (fu_indicator & 0xe0) | (fu_header & 0x1f)
4、代码实现
void CVAUClientSource::AnalyzeHeader(unsigned char * src, int len){ unsigned char head1 = *src;//获取第一个字节 unsigned char head2 = *(src+1);//获取第二个字节 unsigned char type = head1 & 0x1f;//获取FU indicator的类型域, if (type==0x1c)//判断NAL的类型为0x1c=28,说明是FU-A分片 {//fu-a unsigned char flag = head2 & 0xe0;//获取FU header的前三位,判断当前是分包的开始、中间或结束 if (flag==0x80) {//开始 /*进行处理*/ } else (flag==0x40) {//结束 /*进行处理*/ } else{//中间 /*进行处理*/} } else {//单包数据 /*进行处理*/ } return;}
注意事项:
,1,关于时间戳,需要注意的是h264的采样率为90000HZ,因此时间戳的单位为1(秒)/90000,因此如果当前视频帧率为25fps,那时间戳间隔或者说增量应该为3600,如果帧率为30fps,则增量为3000,以此类推。
1)第一个FU-A包的FU indicator:F应该为当前NALU头的F,而NRI应该为当前NALU头的NRI,Type则等于28,表明它是FU-A包。FU header生成方法:S = 1,E = 0,R = 0,Type则等于NALU头中的Type。
2)后续的N个FU-A包的FU indicator和第一个是完全一样的,如果不是最后一个包,则FU header应该为:S = 0,E = 0,R = 0,Type等于NALU头中的Type。
3)最后一个FU-A包FU header应该为:S = 0,E = 1,R = 0,Type等于NALU头中的Type。
因此总结就是:同一个NALU分包厚的FU indicator头是完全一致的,FU header只有S以及E位有区别,分别标记开始和结束,它们的RTP分包的序列号应该是依次递增的,并且它们的时间戳必须一致,而负载数据为NALU包去掉1个字节的NALU头后对剩余数据的拆分,这点很关键,你可以认为NALU头被拆分成了FU indicator和FU header,所以不再需要1字节的NALU头了。
1)第一个FU-A包的FU indicator:F应该为当前NALU头的F,而NRI应该为当前NALU头的NRI,Type则等于28,表明它是FU-A包。FU header生成方法:S = 1,E = 0,R = 0,Type则等于NALU头中的Type。
2)后续的N个FU-A包的FU indicator和第一个是完全一样的,如果不是最后一个包,则FU header应该为:S = 0,E = 0,R = 0,Type等于NALU头中的Type。
3)最后一个FU-A包FU header应该为:S = 0,E = 1,R = 0,Type等于NALU头中的Type。
因此总结就是:同一个NALU分包厚的FU indicator头是完全一致的,FU header只有S以及E位有区别,分别标记开始和结束,它们的RTP分包的序列号应该是依次递增的,并且它们的时间戳必须一致,而负载数据为NALU包去掉1个字节的NALU头后对剩余数据的拆分,这点很关键,你可以认为NALU头被拆分成了FU indicator和FU header,所以不再需要1字节的NALU头了。
- FU-A拆包方式小议
- FU-A STAP-A 拆包 打包 小议
- RFC3984中FU-A拆包方式
- FU-A分包方式说明
- rtp打包的FU-A方式
- FU-A分包方式,以及从RTP包里面得到H.264数据和AAC数据的方法
- FU-A分包方式,以及从RTP包里面得到H.264数据和AAC数据的方法
- FU-A分包方式,以及从RTP包里面得到H.264数据和AAC数据的方法
- FU-A分包方式,以及从RTP包里面得到H.264数据和AAC数据的方法
- FU-A分包方式,以及从RTP包里面得到H.264数据和AAC数据的方法
- FU-A分包方式,以及从RTP包里面得到H.264数据和AAC数据的方法
- FU-A分包方式,以及从RTP包里面得到H.264数据和AAC数据的方法
- FU-A分包方式,以及从RTP包里面得到H.264数据和AAC数据的方法
- FU-A分包方式,以及从RTP包里面得到H.264数据和AAC数据的方法
- FU-A分包方式,以及从RTP包里面得到H.264数据和AAC数据的方法
- FU-A分包方式,以及从RTP包里面得到H.264数据和AAC数据的方法
- FU-A分包方式,以及从RTP包里面得到H.264数据和AAC数据的方法
- FU-A分包方式,以及从RTP包里面得到H.264数据和AAC数据的方法
- 物理引擎box2d的学习心得
- Git入门指南二:初次运行Git前的配置
- Cocos2d-x里Javascript开发的一些要点
- 企业项目开发中可遵循的时间管理守则-华为时间管理
- java实现二叉树的先序、中序、后序遍历
- FU-A拆包方式小议
- winn7自带的IIS实现FTP服务器的架设
- Linux系统调用过程学习笔记
- Hadoop小结连载:Hadoop概述
- php 多个input上传文件或图片
- 学习方法(1)
- Android中的常用控件及其基本用法
- 【转载】大数据:“人工特征工程+线性模型”的尽头
- Select标签下拉列表二级联动级联