音視頻封裝格式:AAC音頻基礎和ADTS打包方案詳解

問題背景:

現在主流的封裝格式支持的音視頻編碼標配是H264+AAC,其中像TS、RTP、FLV、MP4都支持音頻的AAC編碼方式。當然,後繼者不乏Opus這種編碼方式,它主要應用在互聯網場景,比如現在谷歌的WebRTC音視頻解決方案就用的Opus,最新發布的Android10支持的音視頻編碼方式就是AV1和Opus,但是AAC目前在廣電,安防,電影院等還是應用最多,Opus目前還不足以威脅到AAC的地位。本篇文章準備講解下AAC的封裝格式ADTS字段含義和解封裝,順便講解下AAC編碼的一些基本情況,如果你只關心解封裝,直接看【AAC的封裝格式】這節即可。

關注公衆號,瞭解更多!

AAC基本概況:

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。

 

和AC3編碼關係:

和AC3關係不大,AC3早於AAC,是由AAC的發起單位杜比實驗室和日本先鋒合作研製的新編碼方式。AAC能輸出AC-3的任何碼率,勝過AC-3,壓縮率更高,但技術上更加複雜。

 

AAC背景和發展:

1997年制定了不兼容MPEG-1的音頻標準MPEG-2 NBC即MPEG-2 AAC;

1999年AAC又增加了LTP和PNS工具,形成了MPEG-4 AAC V1;

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把頻譜切割開來,低頻單獨編碼保存主要成分,高頻單獨放大編碼保存音質,“統籌兼顧”了,在減少文件大小的情況下還保存了音質,完美的化解這一矛盾。

2. PS指“parametric stereo”(參數立體聲)。原來的立體聲文件文件大小是一個聲道的兩倍。但是兩個聲道的聲音存在某種相似性,根據香農信息熵編碼定理,相關性應該被去掉才能減小文件大小。所以PS技術存儲了一個聲道的全部信息,然後,花很少的字節用參數描述另一個聲道和它不同的地方。

 

AAC編碼技術參數:

採樣率範圍:8KHz-96KHz 範圍比較廣,就是一秒在模擬信號上進行多少次採樣;

碼率:8kbps-576kbps,支持範圍比較寬,在壓縮比和質量上都能考慮到;

聲道:最多支持48個主聲道,16個低頻聲道,聲音細節更豐富,音樂場景也用的多;

採樣精度:就是一個採樣點需要在計算機表示佔用的字節數,一般用2字節16bit表示;

 

AAC編碼的主要規格:

根據不同的編碼技術,AAC的編碼分爲九種規格,這和H264的編碼規格大同小異。

1. MPEG-2 AAC LC低複雜度規格(Low Complexity)編碼方式比較簡單,沒有增益控制,但是提高了編碼效率,在中等碼率的編碼效率和音質方面,都能找到平衡點。

2. MPEG-2 AAC Main 主規格

3. MPEG-2 AAC SSR 可變採樣率規格(Scaleable Sample Rate)

4. MPEG-4 AAC LC 低複雜度規格(Low Complexity)

5. MPEG-4 AAC Main 主規格--包含了除增益控制之外的全部功能,音質最好

6. MPEG-4 AAC SSR 可變採樣率規格(Scaleable Sample Rate)

7. MPEG-4 AAC LTP 長時期預測規格(Long Term Prediction)

8. MPEG-4 AAC LD 低延遲預測規格(Low Delay)

9. MPEG-4 AAC HE 高效率規格(High Efficency)--這種規格適合用於低碼率編碼,有Nero-ACC編碼器支持,是一種成熟的商用編碼器。

 

目前使用最多的就是LC和HE(適合降低碼率),流行的Nero AAC編碼程序支持LC、HE、HEv2三種規格的,而且編碼後的AAC音頻,規格都顯示LC。其中HE就是在AAC(LC)編碼技術上增加SBR技術,HEv2就是AAC(LC)上技術上不僅僅增加了SBR技術,同時也增加了PS技術。

所以一般的商業音頻編碼器只支持部分編碼規格,這也是我們選擇編碼器的重要考慮因素之一,因爲不同的編碼規格支持的音頻採樣率,碼率都不一樣,背後採用的編碼技術和算法複雜度也不一樣。

AAC編碼方式特點:

1. AAC高壓縮比的音頻編碼方式,比G7xx、MP3、AC3系列的壓縮比都高,並且質量和CD差不多,但是和比較新的Opus還是差點,不過Opus目前還未充分普及;

2. AAC也採用了變換編碼算法,採用了更高的濾波器組,這是壓縮高的原因;

3. AAC爲了提高壓縮比,還採用了噪聲重整,反向自適應預測,聯合立體聲和量化霍夫曼編碼算法等新技術;

4. AAC支持了更多的採樣率和比特率,支持了1-48個音軌和多達15個低頻音軌,具有多種語言兼容能力;

5. AAC支持了更寬的聲音頻率範圍,從8KHz-96KHz,遠寬於MP3的16KHz-48KHz範圍;

6. AAC特殊的算法可以保有聲音頻率甚高和甚低頻率。聲音細節更豐富更清晰更接近原聲;

7. AAC採用了優化算法,導致解碼端簡單,降低了解碼端的處理複雜度;

 

AAC的封裝格式:

 

AAC封裝類型:

 

1. ADIF:Audio Data Interchange Format音頻數據交換格式,這種格式一般應用在將音頻通過寫文件方式存儲在磁盤裏,不能進行隨機訪問,不允許在文件中間開始進行解碼。只有拿到整個文件時才能開始進行渲染播放,這種暫時還沒用到,不是這篇文章的重點。

2. ADTS:Audio Data Transport Stream 音頻數據傳輸流。這種格式的特徵是用同步字節進行將AAC音頻截斷,然後可以允許客戶端在任何地方進行解碼播放,適合網絡傳輸場景。這也是本文介紹的封裝格式重點。

ADTS的格式如下:

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各個字段的取值範圍:

1. Profile 取值:

Object Type ID

Aduio Object Type

備註

1

AAC Main

 

2

AAC LC

最常用

3

AAC LTR

 

4

SBR

 

5

AAC scalable

 

 

2. Sampling Frequency Index採樣率取值

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

 

 

3. Channel Configuration通道數取值

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、MP4、FLV中進行打包發送傳輸。下面的代碼通過讀取一個文件流,獲取裏面的ADTS信息和音頻幀。

1. 先定義ADTS頭的結構體

 

2. 讀取文件流的第一個ADTS音頻幀的頭部數據,並解析裏面的長度;

 

3. 再根據長度讀取裏面的音頻裸數據;

 

4. 不斷循環即可完成頭部數據的解析和其裸數據的讀取;

 

總結:

這篇文章初步講解了AAC音頻編碼的基礎知識,同時引出了AAC裸數據打包音頻幀的兩種方式,其實ADTS給出了用工具分析的實例和進行解封裝的示意代碼,對平時AAC打包FLV、MP4、TS等封裝格式打下基礎。

 

 


今天就說這麼多,祝您中秋快樂,工作順利!

 

往期回顧文章:

音視頻封裝:MPTG2-TS 媒體封裝實例解析和說明

音視頻基礎知識-時間戳的理解

MPEG-PS和MPTG-TS 媒體封裝實例解析和說明

 

 

 


個人轉載內容至朋友圈和羣聊天,無需特別申請版權許可。

記得右下角點“在看”,還可以把訂閱號加星標,這樣防止遺漏哦!

 

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