使用libfdk-aac编码所需注意的细节

背景

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提供如上所示的枚举类型与几种封装格式对应。

  • TT_MP4_RAW就是表示裸AAC码流,没有任何方式的封装
  • TT_MP4_ADIF和TT_MP4_ADTS分别是ADIF和ADTS格式
  • TT_MP4_LATM_MCP1和TT_MP4_LATM_MCP0 是LATM封装格式,一个是带内传输StreamMuxConfig,一个是带外传输
  • TT_MP4_LOAS就是LOAS

在流媒体应用中使用的格式是ADTS,LATM:

  1. ADTS对应的RTP封装标准为RFC3640
  2. LATM对的标准为RFC6461

这两个标准在前面的文件有详细介绍。当然也可以直接在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即可。但有两点需要注意的地方:

  1. audio frame的长度设置

在流媒体应用中,音频的采集周期最小采样周期为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的数据就是分两次送入编码器。

  1. 设置复用的audio frame的个数

将编码参数的需要的源数据长度设置为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)。

你可能感兴趣的:(AAC)