压制组装机 sockets dictionary unix split Zeptojs 软件测试项目实战案例 ie内核浏览器怎么设置 python与机器学习 linux 获取系统时间 python刷题 maya曲线建模 maven插件 python图形界面开发 python入门例子 python自学入门 java正则表达式 java安装配置 java中泛型 java环境包 java时间戳转换 java格式化日期 python网站开发实例 php项目实例 php开发教程 cms教程 电子商城系统 微信昵称找人的软件 R语言初学者指南 linux定时任务 c4dr19 暴力猴插件 脚本网站 edquota 抖音APP下载 内存条有什么用 苹果手机怎么微信双开 mac办公软件 租房管理软件 产品修图
当前位置: 首页 > 学习教程  > 编程语言

RTP包分析

2020/12/28 19:34:39 文章标签:

RTP包分析 记录一下对RTP包的理解 RTP包头 上图展示了RTP包的具体信息结构,字段明确如下: RTP头部一般固定会有12字节。 V:版本号,2比特,用来标示使用RTP版本; P:填充位,1比特&am…

RTP包分析

记录一下对RTP包的理解

RTP包头

在这里插入图片描述

上图展示了RTP包的具体信息结构,字段明确如下:

RTP头部一般固定会有12字节。
V:版本号,2比特,用来标示使用RTP版本;
P:填充位,1比特,置成1,表示此包后面会一定数目的填充比特;
X:扩展位,1比特,置成1,表示此包固定头部后面会跟着一个扩展头部;CC:CSRC计数位,4比特,表示固定头部后面CSRC识别符的个数;
M:标示位,1比特,具体含义由特定协议解释;
PT:负载类型(Payload Type),7比特,表示具体的负载类型,比如音频、视频、文档等;
sequence number:序列号,16比特,发送方在每发送完一个RTP包后就将该值增加1,接收方可以由该值检测包的丢失及恢复包序列。序列号的初始值是随机的;
timestamp:时间戳,32比特,表示RTP数据包中第一个字节的采样时间;synchronization source (SSRC) identifier:同步源标示符,32比特,表示RTP数据包的来源,在同一个RTP会话中不可能存在两个相同的SSRC,SSRC的值是随机选取的;
contributing source (CSRC) identifiers:贡献源列表,0到15项,每项32比特,表示此包中负载的所有贡献源。若贡献源多于15个,仅识别15个,CSRC由混合器插入,便于接收端正确识别出会话者的身份。

头部之后加的都是负载,头部信息中SSRC需要关注,用来区分音频和视频流的唯一ID

H264负载内容:

H264在网络中传输的基本单元为NALU
NALU结构:NALU header(1byte) + NALU payload
header 部分可以判断类型等信息,从右往左5个bit位

各个类型的帧判断通过头来进行:

SPS: 0x67 header & 0x1F = 7SEI: 0x66 header & 0x1F = 6
P Frame: 0x41 header & 0x1F = 1I Frame: 0x65 header & 0x1F = 5
PPS: 0x68 header & 0x1F = 8

RTP中H264拆包规则:

  1. 单NALU: P帧或者B帧比较小的包,直接将NALU打包成RTP包进行传输
    RTP header(12bytes) + NALU header (1byte) + NALU payload
  2. 多NALU: 特别小的包几个NALU放在一个RTP包中
  3. FUs(Fragment Units): I帧长度超过MTU的,就必须要拆包组成RTP包了,有FU-A
    RTP header (12bytes)+ FU Indicator (1byte) + FU header(1 byte) + NALU payload
    针对多个FU来说有如下规则:
    NALU头被分散填充到FU indicator和FU header里面了,bit位按照从左到右编号0-7来算,nalu头中0-2前三个bit放在FU indicator的0-2前三个bit中,后3-7五个bit放入FU header的后3-7五个中 ,因此查看I帧p帧类型,遇到FU分片的,直接看第二个字节,即Fu header后五位,这个跟直接看NALU头并无差异,一般有:0x85,0x05,0x45等等
    还原数据帧时,照旧从左到右,Fu header前两个bit表示start和end标记,start为1表示一个i帧分片开始,end为1表示一个i帧分片结束
    看第一个字节FU Indicator,照旧从左到右,Fu Indicator前三个bit是NALU头的前三个bit,后五位为类型FU-A:28(11100),FU-B:29(11101),RTP抓包看下来整个字节是0x7c开头,如果不是分片,第一字节就是NALU头,如:0x67,0x68,0x41等

RTP抓包分析:
SPS包:
在这里插入图片描述

图中可以看出头部为0x67,即为sps包

I帧包(分片包为例):
I帧分片开始:
在这里插入图片描述
I帧分片开始,第一个字节FU Indicator,0x7c, 后五位11100,28,FU-A
第二个字节FU Header,0x85,前两个bit start位1,end位0 表示 分片开始,后五个bit值5,I帧

I帧分片
在这里插入图片描述
I帧分片,0x7c开头,第二个字节0x05, FU Header start和end位 0,后五个bit值5,I帧

I帧分片结束
在这里插入图片描述
I帧分片结束,7c开头,第二个字节0x45,FU Headr,start 0,end1,后五个bit值5,I帧, Mark标记一帧结束

AAC封包:
过程如下:
需要将aac的前7个字节的ADTS去掉;

  1. 添加12字节的RTP Header;
  2. 添加2字节的AU_HEADER_LENGTH;
  3. 添加2字节的AU_HEADER;
  4. 从第17字节开始就是payload(去掉ADTS的aac数据)数据了

格式:
AU-headers-length AU-header AU AU-header AU

一个RTP包中可以有一个AU-headers-length 和 n个AU-header和 n个AU(AU每包实际音频数据流)
AU-headers-length
头两个字节表示au-header的长度,单位是bit。 一个AU-header长度是两个字节(16bit)因为可以有多个au-header所以AU-headers-length的值是 16的倍数,一般音频都是单个音频数据流的发送,所以AU-headers-length的值是16

//AU_HEADER_LENGTH

bytes[12] = 0x00; //高位

bytes[13] = 0x10; //低位

因为单位是bit, 除以8就是auHeader的字节长度;又因为单个auheader字节长度2字节,所以再除以2就是auheader的个数。

AU-header

au-header的高13个bits就是一个au 的字节长度:

//AU_HEADER

bytes[14] = (byte)((len & 0x1fe0) >> 5); //高位

bytes[15] = (byte)((len & 0x1f) << 3); //低位

这样就能得到多个au的长度


本文链接: http://www.dtmao.cc/news_show_550301.shtml

附件下载

相关教程

    暂无相关的数据...

共有条评论 网友评论

验证码: 看不清楚?