libfdk-aac源码中提供了一个编码的示例程序,文件为aac-enc.c
,演示了编码API基本的调用流程,流程也比较简单,看看示例代码就明白了。这里要讲的是应用在rtp流媒体系统时,所需注意的细节。
typedef enum {
TT_UNKNOWN = -1, /**< Unknown format. */
TT_MP4_RAW = 0, /**< "as is" access units (packet based since there is
obviously no sync layer) */
TT_MP4_ADIF = 1, /**< ADIF bitstream format. */
TT_MP4_ADTS = 2, /**< ADTS bitstream format. */
TT_MP4_LATM_MCP1 = 6, /**< Audio Mux Elements with muxConfigPresent = 1 */
TT_MP4_LATM_MCP0 = 7, /**< Audio Mux Elements with muxConfigPresent = 0, out
of band StreamMuxConfig */
TT_MP4_LOAS = 10, /**< Audio Sync Stream. */
TT_DRM = 12 /**< Digital Radio Mondial (DRM30/DRM+) bitstream format. */
} TRANSPORT_TYPE;
在编码前,需要告诉编码器使用的封装格式,关于封装格式在前面的文件有介绍。libfdk-acc提供如上所示的枚举类型与几种封装格式对应。
在流媒体应用中使用的格式是ADTS,LATM:
这两个标准在前面的文件有详细介绍。当然也可以直接在RTP包中携带RAW码流(设置为TT_MP4_RAW),但是与第三方会对通不了,因为没有标准支持。LOAS与RAW一样,也没有标准支持。
在示例代码中,设置的封装格式为TT_MP4_ADTS,编码规格为AAC-LC。那么需要使用RFC3640的方式进行RTP封包。
有一点要注意的如果将规格设置为AAC-LD,封装格式是不能选择为ADTS的,aacEncEncode会报错。需要选择为TT_MP4_RAW或TT_MP4_LATM_MCP1,TT_MP4_LATM_MCP0,TT_MP4_LOAS。
一般的情况下会使用LATM和带内传输StreamMuxConfig的方式进行RTP封包,这种方式最简单,设置编码参数时将TRANSPORT_TYPE
设置为TT_MP4_LATM_MCP1值,直接将编码后的数据做为RTP Payload即可。但有两点需要注意的地方:
在流媒体应用中,音频的采集周期最小采样周期为20ms。以采样率48000,单声道为例,16位,采样周期20ms的数据大小为: 0.02*48000*2*1 = 1920
,可以理解为20ms的数据为一个audio frame,大小为1920个字节。
如果采用LATM,AAC-LD规格则,libfdk-aac的默认audio frame为512采样点,也就是往aacEncEncode
送入pcm数据字节数要求是1024(512*2)。显然1920并不能被1024整除。处理时会很不方便。可以通过下面这个参数调大小
AACENC_GRANULE_LENGTH =
0x0105, /*!< Core encoder (AAC) audio frame length in samples:
- 1024: Default configuration.
- 512: Default length in LD/ELD configuration.
- 480: Length in LD/ELD configuration.
- 256: Length for ELD reduced delay mode (x2).
- 240: Length for ELD reduced delay mode (x2).
- 128: Length for ELD reduced delay mode (x4).
- 120: Length for ELD reduced delay mode (x4). */
那么对AAC-LD,设置值为480(注意这个值是采样点数),则要求传入aacEncEncode
中的数据长度即为480*2=960字节,相当于10ms的数据,那么20ms的数据就是分两次送入编码器。
将编码参数的需要的源数据长度设置为480后,相当编码器产生一个audio frame对应于10ms的pcm数据。那么20ms数据就是两个audio frame,显然是需要复用。通过下面的参数设置复用帧的个数
AACENC_TPSUBFRAMES =
0x0303, /*!< Number of sub frames in a transport frame for LOAS/LATM or
ADTS (default 1).
- ADTS: Maximum number of sub frames restricted to 4.
- LOAS/LATM: Maximum number of sub frames restricted to 2.*/
如上所示,通过AACENC_TPSUBFRAMES
参数将帧的复用个数设置2,这样便可以一次处理20ms的数据了,即每个rtp包携带两个audio frame(默认这个参数的值为1)。