使用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)。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章