RFC3640中对AAC进行RTP打包方式介绍
总括
RFC3640和RFC6416定义了两种对MPEG-4 Stream的RTP封包方式。这里只介绍对音频码流(即AAC)的封装方式。先从RFC3640开始。如果有RTP打包音视频码流的开发经验,下面的一些知识点,理解起来会简单些。
RFC 3640中定义了对MPEG-4 Elementary stream(包括audio,video,mpeg4 system)通过RTP封包的方式。下面所列的是支持的MPEG4-4 Stream的类型
This specification defines a general and configurable payload structure to transport MPEG-4 elementary streams, in particular MPEG-4 audio (including speech) streams, MPEG-4 video streams and also MPEG-4 systems streams, such as BIFS (BInary Format for Scenes),OCI (Object Content Information), OD (Object Descriptor) and IPMP(Intellectual Property Management and Protection) streams.
两个概念
1.Signaling by MIME Format Parameters
RFC 3640支持多种MPEG-4 stream及打包方式,所以需要定义MIME Format标识RTP Payload具体携带是哪一种stream或打包方式(如video,audio,appliation)。那么每种MIME Format Pamraeters就是该格式下,所携带的码流的参数信息。MIME Foramte Parameters并非在RTP码流中携带,而是通过另外一种协议携带,比如最常见的就是通过sdp协议携带。
RFC 3640 Audio 对应的Media Type定义为 mpeg4-generic
在rfc 3640定义了这些MIME Format Pamrameters名字及意义,具体的可以直接可以rfc 3640的第4章
2.MPEG Access Units
简称AU,可以理解成可解码的最小数据单元,在audio stream中就是一个audio frame。
An MPEG Access Unit (AU) is the smallest data entity to which timing information is attributed.In the case of audio, an Access Unit may represent an audio frame and in the case of video, a picture.
RTP的封装
- 一个rtp包携带一个AU,在audio stream中就是一个audio frame。
- 一个rtp包中携带多个AU,一个编码后的audio frame通常是比较小的(通常是100~300的字节),一个rtp(通常是1000个字节以上)通常是可以携带多个audio frame。在rtp payload中就被封装成多个AU。
- 一个rtp包中可携带一个AU的片段,多个rtp包携带一个AU,类似RTP打包的H264/265 FU-A模式,这种情况是针对video stream等大数据量的码流。对audio stream来说,是不会出现这种情况的。
如下所示为码流结构
这里要注意的是,这些字段并不是固定字段(按需携带,可有可无),所以码流结构图描述只是字段的名字,并没有给出字段的位数(位数也是可变的)。这个跟常见的码流结构定义不一样,比如rtp for h264/h265 rfc中,对字段名和长度都进行详细的规定。
下面逐一对字段意思进行解释
AU Header Section
下图是其结构图,其中包含的字段也是可变的(字段可有可无,长度可变)
AU Header Section = AU-Headers-lengths + AU-header + Padding Bit
AU-header 可以有0~n个,为0个时则整个AU Header Section都不会携带。一个AU-header对应一个AU,AU-header中包含对应AU解码所需的一些参数信息。
AU-Headers-Lengths 固定的两个字节的长度,表示AU-Headers的总长度(单位是位),所以AU-Headers所占的字节数=AU-Headers-Lengths/8
Padding Bits: 所有的Au-Header的总长度必须是整数个字节,如果不够则添加Padding Bit
AU-header
如上图所示为AU-header的结构及字段意义,AU-Size,AU-Index,AU-Index-delta为固定字段,其余的几个字段都是码流的参数信息,这些字段都是按需出现的。如果MIME format parameter中携带了对应的属性说明,则就存在对应的字段。
- AU-size:
就是整个数据帧的长度
- AU-Index:
Indicates the serial number of the associated Access Unit
- AU-Index-delta:
就是AU-Index
关于AU-Index和AU-Index-delta,rfc中描述的我没琢磨清楚,按我的理解,用在AU fragement(或interleaving模式)情况下,RTP payload携带的是AU的分片,那么AU-Index/AU-Index-delta就是标识分片的顺序(以加1递增)。那么除此之外,AU携带一个可解码的完整的audio frame时,AU-Index/AU-Index-delta填0即可)
打包AAC
通过RTP打包AAC,需要结合一种协议携带Format Parameters。最常用的是sdp,rfc 3640定义了一些具体模式的约束。这里我们主要是关心携带AAC的情况。
在 section 3.3.5和3.3.6分别描述了 Low Bit-rate AAC 和 High Bit-rate AAC sdp所应携带的信息
- Low Bit-rate AAC
rfc中给出如下约束:
1.The maximum size of an AAC frame in this mode is 63 octets(AAC帧的最大长度是63个字节)
2.AAC frames MUST NOT be fragmented when using this mode(这种模式下不可携带AAC 帧片段)
sdp携带参数信息的例子
m=audio 49230 RTP/AVP 96
a=rtpmap:96 mpeg4-generic/22050/1
a=fmtp:96 streamtype=5; profile-level-id=14; mode=AAC-lbr; config=
1388; sizeLength=6; indexLength=2; indexDeltaLength=2;
constantDuration=1024; maxDisplacement=5
- High Bit-rate AAC
这种模式下AAC frame的长度有约束,最大长度为8191个字节(音频数据不会有这么大)
sdp携带参数信息的例子
m=audio 49230 RTP/AVP 96
a=rtpmap:96 mpeg4-generic/48000/6
a=fmtp:96 streamtype=5; profile-level-id=16; mode=AAC-hbr;
config=11B0; sizeLength=13; indexLength=3;
indexDeltaLength=3; constantDuration=1024
这两种模式的区别就是AAC Frame的大小限制。是用Low Bit-rate模式还是High Bit-rate模式,取决于AAC的编码格式。
sizeLength,indexLength,indexDeltaLength,这3个属性值分别描述的是AU-header中AU-size,AU-index,AU-index-delta字段所占的字节数。是一定会携带的,
其它属性则是跟码流的参数相关的,比如config等。
总结
- RTP打包AAC,必须有一种协议可以携带Format Pamraeters,最常用的就是sdp协议
- 一个rtp包中可以包含一个或多个AAC frame(AU)
- 生成码流结构最基础的就是计算好AU-header-lengths和AU-header-section,及子字段AU-size,AU-index,AU-index-delta。如果具体的AAC编码格式有额外的参数信息需要携带,则对照第4节在sdp中携带即可。
一种打包AAC的最简方式
如果AAC编码器产生的码流数据是ATDS格式,那么它已经描述了采样率,通道解码所需等信息,所以sdp及AU-header-section中只包括AU-header-lengths及AU-size,AU-index字段即可。
采用一个RTP包携带一个AAC frame的方式,那么 AU-header-section = AU-header-lengths + AU-size + AU-index,rtp payload = AU-header-section + AU
sdp描述如下
m=audio 49230 RTP/AVP 96
a=rtpmap:96 mpeg4-generic/22050/1
a=fmtp:96 streamtype=5; profile-level-id=14; mode=AAC-lbr; sizeLength=6; indexLength=2; indexDeltaLength=2;
AU-size的长度为6位,AU-index长度为2,那么AU-header-section占一个字节
rtp payload的长度 = AU-header-lengths(两个字节) + AU-header-section(一个字节) + AU的长度
Au-index值填为0
这种方式也是live555对AAC打包的方式
另外当编码器产生的AAC数据为raw data时(不带ATDS),只需sdp和rtp payload中携带解码所需的信息的即可。