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

問題背景:算法

如今主流的封裝格式支持的音視頻編碼標配是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把頻譜切割開來,低頻單獨編碼保存主要成分,高頻單獨放大編碼保存音質,「統籌兼顧」了,在減小文件大小的狀況下還保存了音質,完美的化解這一矛盾。

  1. PS指「parametric stereo」(參數立體聲)。原來的立體聲文件文件大小是一個聲道的兩倍。可是兩個聲道的聲音存在某種類似性,根據香農信息熵編碼定理,相關性應該被去掉才能減少文件大小。因此PS技術存儲了一個聲道的所有信息,而後,花不多的字節用參數描述另外一個聲道和它不一樣的地方。

l AAC編碼技術參數:

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

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

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

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

l 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技術。

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

l AAC編碼方式特色:

  1. AAC高壓縮比的音頻編碼方式,比G7xx、MP三、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的封裝格式:

n AAC封裝類型:

  1. ADIF:Audio Data Interchange Format音頻數據交換格式,這種格式通常應用在將音頻經過寫文件方式存儲在磁盤裏,不能進行隨機訪問,不容許在文件中間開始進行解碼。只有拿到整個文件時才能開始進行渲染播放,這種暫時還沒用到,不是這篇文章的重點。
  2. ADTS:Audio Data Transport Stream 音頻數據傳輸流。這種格式的特徵是用同步字節進行將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各個字段的取值範圍:

  1. Profile 取值:

Object Type ID

Aduio Object Type

備註

1

AAC Main

2

AAC LC

最經常使用

3

AAC LTR

4

SBR

5

AAC scalable

  1. 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

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

  1. 先定義ADTS頭的結構體
  1. 讀取文件流的第一個ADTS音頻幀的頭部數據,並解析裏面的長度;
  1. 再根據長度讀取裏面的音頻裸數據;
  1. 不斷循環便可完成頭部數據的解析和其裸數據的讀取;

總結:

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

圖片描述瞭解更多關於音視頻IOT,歡迎關注公衆號:智媒黑板報

相關文章
相關標籤/搜索