問題背景:算法
如今主流的封裝格式支持的音視頻編碼標配是H264+AAC,其中像TS、RTP、FLV、MP4都支持音頻的AAC編碼方式。固然,後繼者不乏Opus這種編碼方式,它主要應用在互聯網場景,好比如今谷歌的WebRTC音視頻解決方案就用的Opus,最新發布的Android10支持的音視頻編碼方式就是AV1和Opus,可是AAC目前在廣電,安防,電影院等仍是應用最多,Opus目前還不足以威脅到AAC的地位。本篇文章準備講解下AAC的封裝格式ADTS字段含義和解封裝,順便講解下AAC編碼的一些基本狀況,若是你只關心解封裝,直接看【AAC的封裝格式】這節便可。網絡
AAC基本概況:ide
l AAC(Advance Audio Coding):工具
即高級音頻編碼,出如今1997年,基於MPEG-2的音頻編碼技術,當時被稱爲MPEG-2 AAC,所以把其做爲MPEG-2(MP2)標準的延伸。是由Fraunhofer IIS、杜比實驗室、AT&T、Sony等公司共同開發,目的是取代MP3格式,隨着MPEG-4(MP4)標準在2000年的成型,則爲AAC也叫M4A。性能
l 和AC3編碼關係:優化
和AC3關係不大,AC3早於AAC,是由AAC的發起單位杜比實驗室和日本先鋒合做研製的新編碼方式。AAC能輸出AC-3的任何碼率,賽過AC-3,壓縮率更高,但技術上更加複雜。ui
l AAC背景和發展:this
1997年制定了不兼容MPEG-1的音頻標準MPEG-2 NBC即MPEG-2 AAC;編碼
1999年AAC又增長了LTP和PNS工具,造成了MPEG-4 AAC V1;spa
2002年在MPEG-4 AAC v1增長了SBR和錯誤魯棒性工具,造成了 HE-AAC;
2004年MPEG-4在HE-AAC引入了PS模塊,提高降碼率性能,造成了EAAC+;
對於1999年、2002年、2004年增長了SBR和PS等編碼技術的統稱爲MPEG-4 AAC;
備註:上面這些SBR PS等縮寫就是音頻的編碼算法代名詞,網上比較多,感興趣的能夠進一步自行搜索。1. SBR技術即Spectral Band Replication(頻段複製)音樂的主要頻譜集中在低頻段,高頻段幅度很小,但很重要,決定了音質。若是對整個頻段編碼,如果爲了保護高頻就會形成低頻段編碼過細以至文件巨大;如果保存了低頻的主要成分而失去高頻成分就會喪失音質。SBR把頻譜切割開來,低頻單獨編碼保存主要成分,高頻單獨放大編碼保存音質,「統籌兼顧」了,在減小文件大小的狀況下還保存了音質,完美的化解這一矛盾。
l AAC編碼技術參數:
採樣率範圍:8KHz-96KHz 範圍比較廣,就是一秒在模擬信號上進行多少次採樣;
碼率:8kbps-576kbps,支持範圍比較寬,在壓縮比和質量上都能考慮到;
聲道:最多支持48個主聲道,16個低頻聲道,聲音細節更豐富,音樂場景也用的多;
採樣精度:就是一個採樣點須要在計算機表示佔用的字節數,通常用2字節16bit表示;
l AAC編碼的主要規格:
根據不一樣的編碼技術,AAC的編碼分爲九種規格,這和H264的編碼規格大同小異。
目前使用最多的就是LC和HE(適合下降碼率),流行的Nero AAC編碼程序支持LC、HE、HEv2三種規格的,並且編碼後的AAC音頻,規格都顯示LC。其中HE就是在AAC(LC)編碼技術上增長SBR技術,HEv2就是AAC(LC)上技術上不只僅增長了SBR技術,同時也增長了PS技術。
因此通常的商業音頻編碼器只支持部分編碼規格,這也是咱們選擇編碼器的重要考慮因素之一,由於不一樣的編碼規格支持的音頻採樣率,碼率都不同,背後採用的編碼技術和算法複雜度也不同。
l AAC編碼方式特色:
AAC的封裝格式:
n AAC封裝類型:
ADTS的格式以下:
n AAC封裝頭字段:
ADIF的格式:
adif_sequence
adif_header + byte_alignment + raw_data_stream
adif_header + byte_alignment + raw_data_block......+ raw_data_block
ADIF Header頭信息以下:
ADTS的格式:
adts_sequence
adts_frame + adts_frame + ...... + adts_frame
adts_fixed_header + adts_variable_header + error_check + raw_data_block + error_check
ADTS header 的固定頭和可變頭信息:
固定頭意思就是一旦音頻文件造成,全部幀的信息頭字段意義都是同樣的,可是可變頭說的是每一個幀這裏面字段都有不同的地方,不要理解爲無關緊要的意思。
ADTS幀頭各個字段和含義:
序號
域
長度bits
說明
解釋
1
Syncword
12
all bits must be 1
老是0xFFF,表明一個ADTS幀的開始,做爲分界符,用於同步每幀起始位置。
2
ID即MPEG version
1
0 for MPEG-4, 1 for MPEG-2
通常用0,由於都是屬於MPEG的規範。
3
Layer
2
always 0
老是00
4
Protection Absent
1
set to 1 if there is no CRC and 0 if there is CRC
這裏表明是否有CRC檢驗字段,1表明沒有,0表明有。
5
Profile
2
the MPEG-4 Audio Object Type minus 1
表明使用哪一個級別和規範的AAC,其中01表明Low Complexity(LC),其中profile等於Audio Object Type的值減1,其中全部Audio Object Type值在下面所示。
6
Sampling Frequency Index
4
MPEG-4 Sampling Frequency Index (15 is forbidden)
採樣率下標,因爲AAC的採樣率範圍是8KHz-96KHz,因此具體用那個,這個字段決定。
7
Private Bit
1
set to 0 when encoding, ignore when decoding
通常默認0便可
8
Channel Configuration
3
MPEG-4 Channel Configuration (in the case of 0, the channel configuration is sent via an inband PCE)
通道配置即聲道數,通常2表示立體聲雙聲道。具體取值範圍參考下表。
9
Originality copy
1
set to 0 when encoding, ignore when decoding
通常默認0便可
10
Home
1
set to 0 when encoding, ignore when decoding
通常默認0便可
11
Copyrighted identification bit
1
set to 0 when encoding, ignore when decoding
通常默認0便可
12
Copyrighted identification Start
1
set to 0 when encoding, ignore when decoding
通常默認0便可
13
Aac Frame Length
13
this value must include 7 or 9 bytes of header length: FrameLength = (ProtectionAbsent == 1 ? 7 : 9) + size(AACFrame)
一個ADTS幀的長度包括ADTS頭和AAC原始流。用AAC原始流長度+7或者9。
當proection_ansent = 0 則+9
proection_ansent = 1 則+7
14
ADTS Buffer Fullness
11
buffer fullness
0x7FF 說明是碼率可變的碼流。
0x000表明是固定碼率的碼流。
15
Number of AAC Frames
2
number of AAC frames (RDBs) in ADTS frame minus 1, for maximum compatibility always use 1 AAC frame per ADTS frame
ADTS幀中有number_of_raw_data_blocks_in_frame + 1個AAC原始幀。
因此說number_of_raw_data_blocks_in_frame == 0 表示說ADTS幀中有一個AAC數據塊。
(一個AAC原始幀包含一段時間內1024個採樣及相關數據)
16
CRC
16
CRC if protection absent is 0
校驗字段,爲可選字段。
ADTS各個字段的取值範圍:
Object Type ID
Aduio Object Type
備註
1
AAC Main
2
AAC LC
最經常使用
3
AAC LTR
4
SBR
5
AAC scalable
Sampling frequency index
value
備註
0x0 即0000
96000
DVD-Audio、一些 LPCM DVD 音軌、Blu-ray Disc(藍光盤)音軌、和 HD-DVD (高清晰度 DVD)音軌所用所用採樣率
0x1 即0001
88000
0x2 即0010
64000
0x03即0011
48000
miniDV、數字電視、DVD、DAT、電影和專業音頻所用的數字聲音所用採樣率
0x04即0100
44100
音頻 CD, 也經常使用於 MPEG-1 音頻(VCD, SVCD, MP3)所用採樣率
0x05即0101
32000
0x06即0110
24000
0x07即0111
22000
0x08即1000
16000
0x09即1001
12000
0x0a即1010
11025
0x0b即1011
8000
電話所用採樣率, 對於人的說話已經足夠
0x0c即1100
7350
0x0d即1101
reserver
0x0e即1110
reserve
0x0f即1111
escape value
value
number of channels
Audio syntactic list in order received
tips
0
-
-
關於這些字段看下面raw_data_block基本碼流組件說明
1
1
single_channel_element
1
2
2
channel_pair_element()
2
3
3
single_channel_element()
channel_pair_element()
1+2
4
4
single_channel_element()
channel_pair_element()
single_channel_element()
1+2+1
5
5
single_channel_element()
channel_pair_element()
channel_pair_element()
1+2+2
6
5+1
single_channel_element()
channel_pair_element()
channel_pair_element()
lfe_channel_element()
1+2+2+1
7
7+1
single_channel_element()
channel_pair_element()
channel_pair_element()
channel_pair_element()
lfe_channel_element()
1+2+2+2+1
8-15
-
-
保留
ADTS的raw_data_block基本碼流組件,頭部有3位標誌位id_syn_ele,指示六種不一樣類型的元素:
id_syn_ele
數據流
含義
註釋
ID_SCE(0x0)
single_channel_element()
單通道元素基本上只由一個ICS組成。一個原始數據塊最可能由16個SCE組成。
核心算法區
ID_CPE(0x1)
channel_pair_element()
由兩個可能共享邊信息的ICS和一些聯合立體聲編碼信息組成。一個原始數據塊最多可能由16個SCE組成。
核心算法區
ID_CCE(0x2)
coupling_channel_element()
藕合通道元素。表明一個塊的多通道聯合立體聲信息或者多語種程序的對話信息。
核心算法區
ID_LFE(0x3)
lfe_channel_element()
低頻元素。包含了一個增強低採樣頻率的通道。
核心算法區
ID_DSE(0x4)
data_stream_element()
數據流元素,包含了一些並不屬於音頻的附加信息。
擴展流或者用戶數據,非核心算法區
ID_PCE(0x5)
program_config_element()
程序配置元素。包含了聲道的配置信息。它可能出如今ADIF 頭部信息中。
擴展流或者用戶數據,非核心算法區
ID_FIL(0x6)
fill_element()
填充元素。包含了一些擴展信息。如SBR,動態範圍控制信息等。
擴展流或者用戶數據,非核心算法區
實例分析:
用MediaInfo工具能夠查看AAC音頻的基本信息
AAC Audio ES Viewer工具能夠詳細分析每個字節
分析各個字段含義
待分析數據:
固定頭十六進制可變頭十六進制
FF F1 4C 8 0 42 E0 00
固定頭二進制可變頭二進制
1111 1111 1111 0001 0100 1100 1000 0000 0100 0010 1110 0000 0000 0000
固定頭字段含義
syncword :
十六進制:0x0FFF (12 bits) 分界符
二進制:1111 1111 1111
ID:
十進制0 (1 bit) 0 表明MPEG4的AAC
二進制0 (1 bit) 0
layer :
十進制0 (2 bits) 固定填充00,默認
二進制0 0
protection_absent:
十進制1 (1 bit),決定了頭的長度,目前7字節
二進制:1
profile :
十進制:1 [Low Complexity profile (LC)] (2 bits)
二進制:01
sampling_frequency_index:
十進制:3 [48000 Hz] (4 bits)
二進制:0011
private_bit
十進制: 0 (1 bit)
二級制:0
channel_configuration
十進制: : 2 [2 - LF RF] (3 bits)
二級制:10
original/copy
十進制: 0 (1 bit),默認
二進制:0
home:
十進制:0 (1 bit),默認
二進制:0
可變頭信息
copyright_identification_bit:
十進制:0 (1 bit),默認
二進制:0
copyright_identification_start :
十進制:0 (1 bit),默認
二進制:0
frame_length:
十進制:535 (13 bits) 長度,包括頭和實際裸流數據535-7=528
二級制:00 0100 0010 111
adts_buffer_fullness:
十進制:0 (11 bits)
二進制:0 0000 0000 00 表明是固定碼率0x000,可變碼率是0x7FF
number_of_raw_data_blocks_in_frame:
十進制:0 (2 bits),表明後面的實際幀數0+1個AAC幀
二級制:00
AAC幀的裸流
raw_data_block()
核心代碼參考:
咱們在開發中常常遇到這塊就是AAC封裝格式的解析,須要拿到裸流進行播放和提取裏面的相應字段,或者將裸流打包爲ADTS而後封裝到TS、MP四、FLV中進行打包發送傳輸。下面的代碼經過讀取一個文件流,獲取裏面的ADTS信息和音頻幀。
總結:
這篇文章初步講解了AAC音頻編碼的基礎知識,同時引出了AAC裸數據打包音頻幀的兩種方式,其實ADTS給出了用工具分析的實例和進行解封裝的示意代碼,對平時AAC打包FLV、MP四、TS等封裝格式打下基礎。
瞭解更多關於音視頻IOT,歡迎關注公衆號:智媒黑板報