背景
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:
- ADTS對應的RTP封裝標準爲RFC3640
- 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即可。但有兩點需要注意的地方:
- 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的數據就是分兩次送入編碼器。
- 設置複用的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)。