轉自:
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;
}