当RTSP的音频使用AAC格式时, SDP的内容差不多是这样的
v=0
o=- 16128587303007558182 16128587303007558182 IN IP4 WINDOWS-75IDU9Q
s=Unnamed
i=N/A
c=IN IP4 0.0.0.0
t=0 0
a=tool:vlc 3.0.5
a=recvonly
a=type:broadcast
a=charset:UTF-8
a=control:rtsp://192.168.2.195:8554/
m=audio 0 RTP/AVP 96
b=AS:128
b=RR:0
a=rtpmap:96 mpeg4-generic/22050
a=fmtp:96 streamtype=5; profile-level-id=15; mode=AAC-hbr; config=138856e500; sizeLength=13; indexLength=3; indexDeltaLength=3; Profile=1;
a=control:rtsp://192.168.2.195:8554/trackID=4
m=video 0 RTP/AVP 96
b=AS:800
b=RR:0
a=rtpmap:96 H264/90000
a=fmtp:96 packetization-mode=1;profile-level-id=42c01e;sprop-parameter-sets=Z0LAHtoCQKeX/8CgAJ/EAAADAZAAAF2qPFi6gA==,aM43IA==;
a=control:rtsp://192.168.2.195:8554/trackID=5
这些参数是由RFC规范 https://tools.ietf.org/html/rfc3640 定义的
streamtype对于AAC, 固定为5
profile-level-id固定为15. (我也不知道这个值怎么生成)
本文着重说明config, SizeLength, IndexLength, IndexDeltaLength的作用
config是16进制的, 前两个字节1388
, 表示采样率为22050, 1个channel, 后面的56e500
, 我也不知道是什么鬼.
前两个字节的为ios-14996-3中定义的AudioSpecificConfig, 前13个bits的格式为
字段 | 比特数 | 说明 |
---|---|---|
audioObjectType | 5 | aac的profile, 通常情况是1, 或者2 |
samplingFrequencyIndex | 4 | aac的采样频率的索引, 见下表 |
channelConfiguration | 4 | aac的通道数, 1~6表示为相应的通道数量, 7表示8通道 |
samplingFrequencyIndex的取值
值 | 表示的采样频率 |
---|---|
0 | 96000, |
1 | 88200, |
2 | 64000, |
3 | 48000, |
4 | 44100, |
5 | 32000, |
6 | 24000, |
7 | 22050, |
8 | 16000, |
9 | 12000, |
10 | 11025, |
11 | 8000, |
12 | 7350 |
15 | 表示自定义的采样频率, 一般不会出现 |
1388
转换成2进制为0001 0011 1000 1000
audioObjectType为00010
, 即2
samplingFrequencyIndex为0111
, 即7
, 对应的采样频率为22050
channelConfiguration为0001
, 表示channel数量为1
sizeLength=13; indexLength=3; indexDeltaLength=3涉及到音频的AU Header.
AU Header解决了一个RTP包容纳多个音频包的问题
AU-Header包含以下信息
- 当前的RTP包含了多少个音频包?
- 每个音频包的大小是多少?
- 时间戳是多少?
AU-Header数据段的格式为
总体封装 AU-Header封装
+--------------------+ / +------------------------+
| AU-headers-length | / | AU-size
+--------------------+ / +------------------------+
| AU-Header(1) | / |AU-Index / AU-Index-delta
+--------------------+ \ +------------------------+
| AU-Header(1) | \ | CTS-flag
+--------------------+ \ +------------------------+
| ............ | | CTS-delta
+--------------------+ +------------------------+
| AU-Header(n) | | DTS-flag
+--------------------+ +------------------------+
| padding | |DTS-delta
+--------------------+ +------------------------+
| RAP-flag
+------------------------+
| Stream-state |
+------------------------+
字段 | 比特数 | 说明 |
---|---|---|
AU-headers-length | 0或16 | 如果没有AU-Header, 即fmtp中不出现SizeLength等参数时, 此字段不存在. 否则, 使用两个字节来存储所有AU-Header所占用的比特数 (不包含自己, 不包含padding字段), 网络字节序 |
AU-size | 由sizeLength决定 | 表示本段音频数据占用的字节数 |
AU-Index | 由indexLength决定 | 表示本段的序号, 通常0开始 |
AU-Index-delta | 由indexDeltaLength决定 | 表示本段序号与上一段序号的差值 |
其它的值都是可选的, 如果sdp中没有出现相关的参数(或者为0), 则表示它们不出现.
以最简单的情况举例, 假设aac数据长度为200字节, 只有一个au-header.
200
的二进制为0000011001000
. (补足为13 bits)
AU-headers-length
值为16, 因为只有一个au-header, au-header中只有AU-size和AU-Index, 共占用16bits
整个au-header数据段的内容为
0000 0000 0000 1000 0000011001000 000
通常情况下, 一个rtp中只有一个aac包, 不需要加再AU-Header, 那么sdp中的aac参数可以简化为
a=fmtp:96 streamtype=5; profile-level-id=15; mode=AAC-hbr; config=138856e500;