最近在弄rtmp推流AAC格式的音頻流,於是對AAC文件解析一個總結。
第一部分 AAC ADTS格式分析
AAC音頻格式分析
AAC音頻格式有ADIF和ADTS:
ADIF:Audio Data Interchange Format 音頻數據交換格式。這種格式的特徵是可以確定的找到這個音頻數據的開始,不需進行在音頻數據流中間開始的解碼,即它的解碼必須
在明確定義的開始處進行。故這種格式常用在磁盤文件中。
ADTS:Audio Data Transport Stream 音頻數據傳輸流。這種格式的特徵是它是一個有同步字的比特流,解碼可以在這個流中任何位置開始。它的特徵類似於mp3數據流格式。
ADTS格式的文件組成如下:
圖1 AAC ADTS格式文件
AAC ADTS Header結構如下圖所示,1~10字段是固定頭部,11~15字段是可變頭部,CRC字段不一定有內容:
圖2 AAC ADTS header結構
先看一段AAC ADTS的文件內容:
圖3 AAC ADTS格式文件內容示例
解析如下:
(7 or 9)個字節的Header內容:11111111 11111001 01010000 10000000 00010111 00111111 11111100
固定頭(28bit):
syncword(12bit):11111111 1111,0xFFF,ADTS幀的開始
ID(1bit):1, MPEG Version, 0表示是MPEG-4,1表示MPEG-2
layer(2bit):00,一般都是00
protection_absent(1bit):1,1表示包頭沒有CRC校驗字段,0表示有CRC校驗字段
profile(2bit):01, 表示使用哪個級別的AAC
sampling_frequency_index(4bit):0100,表示使用的採樣率下標,指明瞭採樣率,這個例子表示使用了44.1kHz
private_bit(1bit):0,private stream, set to 0 when encoding, ignore when decoding
channel_configuration(3bit):010,表示聲道數
original_copy(1bit):0,originality, set to 0 when encoding, ignore when decoding,
home(1bit):0,set to 0 when encoding, ignore when decoding
可變頭:
copyright_identification_bit(1bit):0,copyrighted stream, set to 0 when encoding, ignore when decoding
copyright_identification_start(1bit):0,copyright start, set to 0 when encoding, ignore when decoding
aac_frame_length(13bit):00 00010111 001(185),AAC幀的長度,該值包含頭部的長度,FrameLength = (ProtectionAbsent == 1 ? 7 : 9) + size(AACFrame)
adts_buffer_fullness(11bit):11111 111111(0x7FF),說明碼率可變的碼流
no_of_raw_data_blocks_in_frame(2bit):00,Number of AAC frames (RDBs) in ADTS frame minus 1, for maximum compatibility always use 1 AAC frame per ADTS frame
CRC(16bit):CRC的校驗字段,該示例沒有校驗字段。
第二部分 RTMP推送AAC音頻流
推送音頻流,所有的音頻包是通過AUDIODATA結構封裝的,該結構如圖4所示。在向RTMP服務器推送音頻流或者視頻流時,首先要推送一個音頻tag(AAC sequence header)和視頻tag(AVC sequence header),沒有這些信息播放端是無法解碼音視頻流的,其中音頻tag格式如下
圖4 音頻數據格式
其中AACAUDIODATA的結構如下圖:
圖5 AAC audio data結構圖
AAC sequence header其實就是AudioSpecificConfiguration,其定義如下:
從上面推論出AAC sequence header內容的前2個字節是0xAF 0x00,我們來看一個示例:
圖7 AAC sequence header示例
AAC sequence header內容是:AF 00 12 10,解析如下:
發送完AAC sequence header後就是AAC的幀數據,每幀的字節存放在AAC header後,長度由header的aac_frame_length字段指定,該值也包含了頭和CRC字段的長度。
另一個比較重要的信息就是RTMP包的時間戳問題,其計算公式是:
frame_duration = frame_sample*1000/sample_rate
AAC一幀的採樣點是1024或者960,該值由哪個字段決定,尚未弄明白,對於44100Hz的採樣率來說,大概就是23.21毫秒。每天會更新論文和視頻,還有如果想學習c++知識在晚上8.30免費觀看這個直播:https://ke.qq.com/course/131973#tuin=b52b9a80
閱讀更多 IT布丁老師 的文章