音視頻學習(十二、AAC格式介紹)

每次都普及這些基礎的時候,都是要轉載別人的文章,因爲我也不熟,也是一邊學習一邊記錄學習的過程,這些基礎知識都是需要補的。

轉載鏈接:AAC ADTS格式分析

12.1 AAC基本介紹

AAC音頻格式:Advanced Audio Coding(高級音頻解碼),是一種由MPEG—4標準定義的有損音頻壓縮格式,由Fraunhofer發展,Dolby,Sony和AT&T是主要貢獻者。

AAC音頻格式有ADIF和ADTS:
ADIF:Audio Data Interchange format音頻數據交換格式。這種格式的特徵是可以確定的找到這個音頻數據的開始,不需要進行在音頻數據流中間開始解碼,即它的解碼必須在明確定義的開始處進行。故這種格式常用在磁盤文件中。

ADTS:Audio Data Transport Stream 音頻數據傳輸流。這種格式的特徵是它是一個有同步字的比特流,解碼可以在這個流中任何位置開始。它的特徵類似於mp3數據流格式。

簡單說:ADTS可以在任意幀解碼,也就是說它每一幀都有頭信息。ADIF只有一個統一的頭,所以必須得到所有的數據後解碼。且這兩種的header的格式也是不同的,目前一般編碼後和抽取出來的都是ADTS格式的音頻流。

在這裏插入圖片描述

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

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

12.2 ADTS介紹

AAC音頻文件的每一幀由ADTS Header和AAC Audio Data組成。結構體如下:
在這裏插入圖片描述

每一幀的ADTS的頭文件都包含了音頻的採樣率,聲道,幀長度等信息,這樣解碼器才能解析讀取。
一般情況下ADTS的頭信息都是7個字節,分爲2部分:

  1. adts_fixed_header();
  2. 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
在這裏插入圖片描述

#define FF_PROFILE_AAC_MAIN 0
#define FF_PROFILE_AAC_LOW  1
#define FF_PROFILE_AAC_SSR  2
#define FF_PROFILE_AAC_LTP  3
#define FF_PROFILE_AAC_HE   4
#define FF_PROFILE_AAC_HE_V2 28
#define FF_PROFILE_AAC_LD   22
#define FF_PROFILE_AAC_ELD  38
#define FF_PROFILE_MPEG2_AAC_LOW 128
#define FF_PROFILE_MPEG2_AAC_HE  131

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數據塊。

12.2 AAC實例解析

下面是ADTS的AAC文件部分:
在這裏插入圖片描述
第一幀的幀頭7個字節爲:0xFF 0xF1 0x4C 0x40 0x20 0xFF 0xFC
分析各個關鍵數值:
111111111111 (syncword)
0 (ID: 0:MPEG-4)
00 (Layer: 總是00)
1 (protection_absent:表示是否誤碼校驗)
01 (profile: 01:ACC LC)
0011 (sampling_frequency_index:採樣頻率)
0 (private_bit)
001 (channel_configuration:聲道)
0 (original_copy)
0 (home)
0 (copyright_id_bit)
0 (copyright_id_start)
0000100000111 (幀長度)
11111111111 (adts_buffer_fullness:0x77表示可變碼流)
00 (number_of_raw_data_blocks_in_frame )

計算幀長度:將二進制 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;
}

還是大神分析的比較詳細,今天又學習到了,音視頻學習後面的路還很長。

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