AAC ADTS格式分析


轉自:

https://blog.csdn.net/jay100500/article/details/52955232

https://blog.csdn.net/andyhuabing/article/details/40983423

https://blog.csdn.net/liukun321/article/details/25337425

http://blog.chinaunix.net/uid-26084833-id-3416600.html

 

AAC的音頻文件格式有ADIF & ADTS:

 

ADIF:Audio Data Interchange Format 音頻數據交換格式。這種格式的特征是可以確定的找到這個音頻數據的開始,不需進行在音頻數據流中間開始的解碼,

即它的解碼必須在明確定義的開始處進行。故這種格式常用在磁盤文件中。

 

ADTS的全稱是Audio Data Transport Stream。是AAC音頻的傳輸流格式。

AAC音頻格式在MPEG-2(ISO-13318-7 2003)中有定義。AAC后來又被采用到MPEG-4標准中。

這種格式的特征是它是一個有同步字的比特流,解碼可以在這個流中任何位置開始。它的特征類似於mp3數據流格式。

 

簡單說,ADTS可以在任意幀解碼,也就是說它每一幀都有頭信息。ADIF只有一個統一的頭,所以必須得到所有的數據后解碼。

且這兩種的header的格式也是不同的,目前一般編碼后的和抽取出的都是ADTS格式的音頻流。

 

有的時候當你編碼AAC裸流的時候,會遇到寫出來的AAC文件並不能在PC和手機上播放,很大的可能就是AAC文件的每一幀里缺少了ADTS頭信息文件的包裝拼接。

只需要加入頭文件ADTS即可。一個AAC原始數據塊長度是可變的,對原始幀加上ADTS頭進行ADTS的封裝,就形成了ADTS幀。

 

AAC音頻文件的每一幀由ADTS Header和AAC Audio Data組成。結構體如下:

 

 

每一幀的ADTS的頭文件都包含了音頻的采樣率,聲道,幀長度等信息,這樣解碼器才能解析讀取。
一般情況下ADTS的頭信息都是7個字節,分為2部分:
adts_fixed_header();
adts_variable_header();
其一為固定頭信息,緊接着是可變頭信息。固定頭信息中的數據每一幀都相同,而可變頭信息則在幀與幀之間可變。

 

 

syncword :同步頭 總是0xFFF, all bits must be 1,代表着一個ADTS幀的開始

ID:MPEG標識符,0標識MPEG-4,1標識MPEG-2

Layer:always: '00'

protection_absent:表示是否誤碼校驗。Warning, set to 1 if there is no CRC and 0 if there is CRC

profile:表示使用哪個級別的AAC,如01 Low Complexity(LC)--- AAC LC。有些芯片只支持AAC LC 。

在MPEG-2 AAC中定義了3種:

 

profile的值等於 Audio Object Type的值減1
profile = MPEG-4 Audio Object Type - 1

 

 

sampling_frequency_index:表示使用的采樣率下標,通過這個下標在 Sampling Frequencies[ ]數組中查找得知采樣率的值。

 

 

channel_configuration: 表示聲道數,比如2表示立體聲雙聲道

 


0: Defined in AOT Specifc Config
1: 1 channel: front-center
2: 2 channels: front-left, front-right
3: 3 channels: front-center, front-left, front-right
4: 4 channels: front-center, front-left, front-right, back-center
5: 5 channels: front-center, front-left, front-right, back-left, back-right
6: 6 channels: front-center, front-left, front-right, back-left, back-right, LFE-channel
7: 8 channels: front-center, front-left, front-right, side-left, side-right, back-left, back-right, LFE-channel
8-15: Reserved

 

 接下來看下adts_variable_header();

 

 frame_length : 一個ADTS幀的長度包括ADTS頭和AAC原始流.

frame length, this value must include 7 or 9 bytes of header length:
aac_frame_length = (protection_absent == 1 ? 7 : 9) + size(AACFrame)
protection_absent=0時, header length=9bytes
protection_absent=1時, header length=7bytes

adts_buffer_fullness:0x7FF 說明是碼率可變的碼流。
number_of_raw_data_blocks_in_frame:表示ADTS幀中有number_of_raw_data_blocks_in_frame + 1個AAC原始幀。
所以說number_of_raw_data_blocks_in_frame == 0 表示說ADTS幀中有一個AAC數據塊。

 

下面是ADTS的AAC文件部分:

 

 

 

 

第一幀的幀頭7個字節為:0xFF 0xF1 0x4C 0x40 0x20 0xFF 0xFC

 分析各個關鍵數值:

111111111111
0
00
1
01
0011
0
001
0
0
0
0
0000100000111(幀長度)
11111111111
00

計算幀長度:將二進制 0000100000111 轉換成十進制為263。觀察第一幀的長度確實為263個字節。

計算方法:(幀長度為13位,使用unsigned int來存儲幀長數值)

unsigned int getFrameLength(unsigned char* str)

{

  if ( !str )

  {

    return 0;

  }

  unsigned int len = 0;

  int f_bit = str[3];

  int m_bit = str[4];

  int b_bit = str[5];

  len += (b_bit>>5);

  len += (m_bit<<3);

  len += ((f_bit&3)<<11);

  return len;

}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM