一SADTS格式:api
ADTS的全稱是Audio Data Transport Stream。是AAC音頻的傳輸流格式。ide
AAC音頻格式在MPEG-2(ISO-13318-7 2003)中有定義。AAC後來又被採用到MPEG-4標準中。ui
1. adts_sequence()編碼
{orm
while (nextbits() == syncword)對象
{ip
adts_frame();ci
}同步
}string
2. adts_frame()
{
adts_fixed_header();
adts_variable_header();
if (number_of_raw_data_blocks_in_frame == 0)
{
adts_error_check();
raw_data_block();
} else
{
adts_header_error_check();
for (i = 0; i <= number_of_raw_data_blocks_in_frame; i++)
{
raw_data_block();
adts_raw_data_block_error_check();
}
}
}
3. adts_fixed_header()
{
syncword: 12 bslbf
ID: 1 bslbf
layer: 2 uimsbf
protection_absent: 1 bslbf
profile: 2 uimsbf
sampling_frequency_index: 4 uimsbf
private_bit: 1 bslbf
channel_configuration: 3 uimsbf
original/copy: 1 bslbf
home: 1 bslbf
}
adts_variable_header()
{
copyright_identification_bit: 1 bslbf
copyright_identification_start: 1 bslbf
frame_length: 13 bslbf
adts_buffer_fullness: 11 bslbf
number_of_raw_data_blocks_in_frame: 2 uimsfb
}
詳細說明下ADTS頭的重要數據部分:
syncword 同步字The bit string ‘1111 1111 1111’,說明一個ADTS幀的開始。
ID MPEG 標示符, 設置爲1.
layer Indicates which layer is used. Set to ‘00’
protection_absent 表示是否誤碼校驗
profile 表示使用哪一個級別的AAC,如01 Low Complexity(LC)--- AACLC
sampling_frequency_index 表示使用的採樣率下標
sampling_frequency_index sampling frequeny [Hz]
0x0 96000
0x1 88200
0x2 64000
0x3 48000
0x4 44100
0x5 32000
0x6 24000
0x7 22050
0x8 16000
0x9 2000
0xa 11025
0xb 8000
0xc reserved
0xd reserved
0xe reserved
0xf reserved
channel_configuration 表示聲道數
frame_length 一個ADTS幀的長度包括ADTS頭和raw data block.
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數據塊並非說沒有。(一個AAC原始幀包含一段時間內1024個採樣及相關數據)
二 封裝AAC爲ADTS幀
一個AAC原始數據塊長度是可變的,對原始幀加上ADTS頭進行ADTS 的封裝,就造成了ADTS幀。一般咱們將獲得的AAC原始幀進行封裝後寫入文件,用經常使用的播放器如千千靜聽便可播放,這是個驗證AAC數據是否正確的方法。
進行封裝前,須要瞭解相關參數,如採樣率,聲道數,原始數據塊的長度等。下面把AAC原始數據幀加工爲ADTS幀,據相關參數填寫組成7字節的ADTS頭。
The ADTS header is defined below -
unsigned int obj_type = 0;
unsigned int num_data_block = frame_length / 1024;
// include the header length also
frame_length += 7;
/* We want the same metadata */
/* Generate ADTS header */
if(adts_header == NULL) return;
/* Sync point over a full byte */
adts_header[0] = 0xFF;
/* Sync point continued over first 4 bits + static 4 bits
* (ID, layer, protection)*/
adts_header[1] = 0xF9;
/* Object type over first 2 bits */
adts_header[2] = obj_type << 6;//
/* rate index over next 4 bits */
adts_header[2] |= (rate_idx << 2);
/* channels over last 2 bits */
adts_header[2] |= (channels & 0x4) >> 2;
/* channels continued over next 2 bits + 4 bits at zero */
adts_header[3] = (channels & 0x3) << 6;
/* frame size over last 2 bits */
adts_header[3] |= (frame_length & 0x1800) >> 11;
/* frame size continued over full byte */
adts_header[4] = (frame_length & 0x1FF8) >> 3;
/* frame size continued first 3 bits */
adts_header[5] = (frame_length & 0x7) << 5;
/* buffer fullness (0x7FF for VBR) over 5 last bits*/
adts_header[5] |= 0x1F;
/* buffer fullness (0x7FF for VBR) continued over 6 first bits + 2 zeros
* number of raw data blocks */
adts_header[6] = 0xFC;// one raw data blocks .
adts_header[6] |= num_data_block & 0x03; //Set raw Data blocks.
在CMMB中,採用AAC音頻壓縮標準,默認情況下,編碼參數以下:雙聲道,採樣率24KHZ,幀長變長,碼流可變碼率的碼流,通常採用的AAC profile爲
AAC-LC。將從CMMB複用幀解析的一個AAC原始幀封裝爲ADTS幀的方法以下:
uint8 aac_buf[ADTS_FRAME_SIZE]={0x0ff,0x0f9,0x058,0x80,0,0x1f,0xfc};
從上述7個字節分析音頻參數以下:
synword--0xfff
ID:0x1--- 1--- MPEG2 identifier,
LAYER--00
protection_absent ---01
profile--01 1 Low Complexity profile (LC) AAC-LC
smaping_freuency_index---0110-->0x06--->採樣率24KHZ
channel_configuration --- aac_buf[3] = 0x08---->2---->雙聲道。。
adts_buffer_fullness--->0x7ff 碼率可變的碼流
現插入長度參數 wDataLen;
void OnAudioAacFrame(byte* data, uint16 wDataLen)
{
unsigned int num_data_block = wDataLen / 1024;
uint16 frame_Length;
frame_Length = wDataLen + 7;
/* frame size over last 2 bits */
aac_buf[3] |= (frame_length & 0x1800) >> 11;// the upper 2 bit
/* frame size continued over full byte */
aac_buf[4] = (frame_length & 0x1FF8) >> 3;// the middle 8 bit
/* frame size continued first 3 bits */
aac_buf[5] |= (frame_length & 0x7) << 5;//the last 3 bit
aac_bug[6] |= num_data_block & 0x03; //Set raw Data blocks.
emcpy(&aac_buf[7],data,wDataLen);
//造成一個ADTS幀寫入文件。
fwrite(aac_buf,wDataLen+7,sizeof(byte),f_audio);
}
三 LATM格
LATM 的全稱爲「Low-overhead MPEG-4 Audio TransportMultiplex」(低開銷音頻傳輸複用),是MPEG-4 AAC制定的一種高效率的碼流傳輸方式,MPEG-2 TS 流也採用LATM 做爲AAC 音頻碼流的封裝格式之 LATM格式也以幀爲單位,主要由AudioSpecificConfig(音頻特定配置單元)與音頻負載組成。
AudioSpecificConfig 描述了一個LATM 幀的信息,音頻負載主要由PayloadLengthInfo(負載長度信息)和PayloadMux(負載淨荷)組成。
AudioSpecificConfig 信息能夠是帶內傳,也能夠是帶外傳。所謂帶內傳,就是指每個LATM 幀,都含有一個AudioSpecificConfig 信息;而帶外傳,
則每個LATM幀都不含有AudioSpecificConfig 信息,而經過其餘方式把AudioSpecificConfig信息發送到解碼端,因爲AudioSpecificConfig 信息通常是不變的,因此只需發送一次便可。因而可知,AudioSpecificConfig 信息採用帶內傳輸可適應音頻編碼信息不斷變化的狀況,而採用帶外傳輸,能夠節省音頻傳輸碼率。帶內或帶外傳,由muxconfigPresent 標誌位決定。例如流媒體應用中,muxconfigPresent 可設置爲0,這樣LATM幀中將不含有AudioSpecificConfig 信息,LATM幀經過RTP包發送出去,AudioSpecificConfig 可經過SDP文件一次性傳送到解碼端。
AudioSpecificConfig 主要參數
numSubFrames 子幀的數目
numProgram 複用的節目數
numLayer 複用的層數
frameLengthType 負載的幀長度類型,包括固定長度與可變長度
audioObjectType 音頻對象類型
samplingFrequency 採樣率
channelConfiguration 聲道配置
音頻負載由若干子幀組成,每一個子幀由PayloadLengthInfo和PayloadMux組成,與ADTS幀淨荷同樣,音頻負載主要包含原始幀數據。
AAC打包成TS流一般有兩種方式,分別是先打包成ADTS或LATM。ADTS的每一幀都有個幀頭,在每一個幀頭信息都同樣的情況下,會有很大的冗餘。LATM格式具備很大的靈活性,每幀的音頻配置單元既能夠帶內傳輸,有能夠帶外傳輸。正由於如此,LATM不只適用於流傳輸還能夠用於RTP傳輸,RTP傳輸時,若音頻數據配置信息是保持不變,能夠先經過SDP會話先傳輸StreamMuxConfig(AudioSpecificConfig)信息,因爲LATM流由一個包含了一個或多個音頻幀的audioMuxElements序列組成。一個完整或部分完整的audioMuxElement可直接映射到一個RTP負載上。
下面是一個audoMuxEmlemt
AudioMuxElement(muxConfigPresent)
{
if (muxConfigPresent)
{
useSameStreamMux;
if (!useSameStreamMux)
StreamMuxConfig();
}
if (audioMuxVersionA == 0)
{
for (i = 0; i <= numSubFrames; i++)
{
PayloadLengthInfo();
PayloadMux();
}.
}
}
能夠很簡單的把ADTS幀轉換爲LATM幀,根據ADTS頭的信息,生成StreamMuxConfig,將ADTS中的原始幀提取出來,前面加上PayloadLengthInfo作爲LATM的音頻幀。按照上述格式打包生成AudioMuxElement,做爲RTP的負載傳輸.
4、 CMMB中的LATM
當CMMB中音頻壓縮標準爲AAC時,默認採用LATM封裝。StreamMuxConfig採用帶外傳輸。StreamMuxConifg中的若干默認參數以下:
audioMuxVersion:0標誌流語法版本號爲0
allStreamSameTiemFraming:1,標誌複用到PayLoadMux()中的全部負載共享一個共同的時基
umSubFrames:0 表示只有一個音頻子幀.
audioObjectType:2 AAC-LC freameLengthType:0 幀長度是可變的
latmBufferFullness:0xFF 碼率可變的碼流
參考:
[1]ISO/IEC 13818-7(2003 MPEG-2 AAC, Second Edition)
[2] ISO13818-7(2006 Fourth edition AAC)
[3] RFC 3016 (rfc3016) - RTP Payload Format for MPEG-4 Audio-Visual Streams
[4] AAC音頻壓縮編碼標準的ADTS與LATM格式分析
[5] GYZ 234-2008: CMMB複用實施指南