AAC 格式分析
一SADTS格式:
???????ADTS的全稱是Audio Data Transport Stream。是AAC音頻的傳輸流格式。
???????AAC音頻格式在MPEG-2(ISO-13318-7 2003)中有定義。AAC后來又被采用到MPEG-4標準中。
???????1. adts_sequence()
???????{
??????????????while (nextbits() == syncword)
??????????????{
?????????????????????adts_frame();
??????????????}
???????}
?
???????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的負載傳輸.
?
四、 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復用實施指南
總結
- 上一篇: linux 安装tomcat 权限不足
- 下一篇: Windows phone 8 学习笔记