1. 程式人生 > >faac編解碼移植和優化

faac編解碼移植和優化

1、下載、編譯和安裝過程:

wget http://downloads.sourceforge.net/faac/faac-1.28.tar.gz
tar zxvf faac-1.28.tar.gz
cd faac-1.28
./configure
make
sudo make install

2、aac配置

1. 開啟faac編碼器引擎。
   faacEncHandle FAACAPI faacEncOpen(   
        unsigned long sampleRate,      // pcm音訊取樣率,8k,16k,44100等
        unsigned int numChannels,      // pcm音訊通道,mono = 1 / stereo = 2 
        unsigned long *inputSamples,   // 一次輸入的樣本數
        unsigned long *maxOutputBytes);// 輸出aac buffer的最大size   
        函式呼叫成功會return一個編碼器faacEncHandle,同時確定輸入樣本數和輸出aac buffer最大size;

    申請輸入buffer及輸出buffer
    int     nPCMBufferSize = inputSamples * nPCMBitSize / 8; //nPCMBitSize 單次樣本位數
    unsinged char*   pbPCMBuffer = new BYTE[nPCMBufferSize];
    unsigned char*   pbAACBuffer = new BYTE[maxOutputBytes];


2. 獲取當前編碼器配置。
   faacEncConfigurationPtr FAACAPI faacEncGetCurrentConfiguration( 
        faacEncHandle hEncoder); //編碼器handle
    函式呼叫成功會返回一個faacEncConfigurationPtr用來檢視及設定編碼器配置。

3. 修改當前編碼器的配置並設定。
   //copy this struct from headfile
   typedef struct faacEncConfiguration{
    /* config version - 配置版本,可以預設不設定*/ 
    int version;
    /* library version - 庫版本,可以預設不設定*/     
    char *name;
    /* copyright string - 版權,可以預設不設定*/   
    char *copyright;       
    /* MPEG version, 2 or 4 - MPEG版本,MPEG2 or MPEG4*/ 
    unsigned int mpegVersion;
    /* AAC object type - AAC物件型別,詳細見補充說明1,取值:1-MAIN 2-LOW 3-SSR 4-LTP*/
    unsigned int aacObjectType;
    /* Allow mid/side coding - 是否允許mid/side coding, 詳細見補充說明2,取值:0-NO 1-YES*/
    unsigned int allowMidside;
    /* Use one of the channels as LFE channel - 是否允許一個通道為低頻通道,取值:0-NO 1-YES*/
    /* LFE(low-frequencyeffects) */
    unsigned int useLfe;
    /* Use Temporal Noise Shaping - 瞬時噪聲定形(temporal noise shaping,TNS)濾波器,取值:0-NO 1-YES*/
    unsigned int useTns;
    /* bitrate / channel of AAC file - AAC檔案的bitrate / channel 取值:0和48000都可以,暫時不清楚這個引數作用*/
    unsigned long bitRate;
    /* AAC file frequency bandwidth - 頻寬 取值:0, 32000,64000都可以,暫時不清楚引數作用*/
    unsigned int bandWidth;
    /* Quantizer quality - 編碼質量,取值:efault=100 LOWER<100 HIGHER>100*/
    /* 預設100,值越大音質越高 */
    unsigned long quantqual;
    /* Bitstream output format (取值:0 = Raw; 1 = ADTS) - 輸出資料型別(是否包包含adts頭),錄製MP4檔案時,要用raw流,ADTS詳細見補充說明3*/
    unsigned int outputFormat;
    /* psychoacoustic model list*/
    psymodellist_t *psymodellist;
    /* selected index in psymodellist*/
    unsigned int psymodelidx;
    /*
    PCM Sample Input Format  - 輸入pcm資料型別
    0 FAAC_INPUT_NULL    invalid, signifies a misconfigured config
    1 FAAC_INPUT_16BIT native endian 16bit
    2 FAAC_INPUT_24BIT native endian 24bit in 24 bits(not implemented)
    3 FAAC_INPUT_32BIT native endian 24bit in 32 bits (DEFAULT)
    4 FAAC_INPUT_FLOAT 32bit floating point
    */
    unsigned int inputFormat;
    /* block type enforcing - 
     * (SHORTCTL_NORMAL/SHORTCTL_NOSHORT/SHORTCTL_NOLONG) 
     */
    int shortctl;
    /*
        Channel Remapping
        Default         0, 1, 2, 3 ... 63  (64 is MAX_CHANNELS in coder.h)
        WAVE 4.0        2, 0, 1, 3
        WAVE 5.0        2, 0, 1, 3, 4
        WAVE 5.1        2, 0, 1, 4, 5, 3
        AIFF 5.1        2, 0, 3, 1, 4, 5 
    */
    int channel_map[64];    
} faacEncConfiguration, *faacEncConfigurationPtr;   

引數設定示例:
第一步:    
    faacEncConfigurationPtr pConfiguration;
    pConfiguration->outputFormat = 1;
    pConfiguration->aacObjectType = LOW;
    pConfiguration->bitRate = 48000;    // or 0
    pConfiguration->bandWidth = 64000;  //or 0 or 32000
    pConfiguration->inputFormat = FAAC_INPUT_16BIT;

    /*下面可以選擇設定*/
    pConfiguration->allowMidside = 1;
    pConfiguration->useLfe = 0;
    pConfiguration->useTns = 0;        
    pConfiguration->quantqual = 100;
    pConfiguration->outputFormat = 1;
    pConfiguration->shortctl = SHORTCTL_NORMAL;  

第二步:
    int FAACAPI faacEncSetConfiguration( //設定編碼器配置
        faacEncHandle hEncoder,
        faacEncConfigurationPtr config);

4.進行編碼操作(PCM to AAC)
    /* 請見步驟1中這部分
    int nPCMBufferSize = inputSamples * nPCMBitSize / 8;
    unsinged char*   pbPCMBuffer = new BYTE[nPCMBufferSize];
    unsigned char*   pbAACBuffer = new BYTE[maxOutputBytes];
    */
    先獲取PCM資料,填充到pbPCMBuffer,單次獲取長度為nPCMBufferSize。

    int FAACAPI faacEncEncode(
        faacEncHandle hEncoder,
        int32_t * inputBuffer,       //pcm輸入buffer, pbPCMBuffer 
        unsigned int samplesInput,   //一次輸入的樣本數(注意不是資料長度 ),samplesInput
        unsigned char *outputBuffer, //AAC輸出buffer, pbAACBuffer 
        unsigned int bufferSize);
        函式呼叫成功會返回實際AAC資料大小,從pbAACBuffer中讀出即可。

5. 結束關閉編碼器退出。
    int FAACAPI faacEncClose(faacEncHandle hEncoder);

    tips:釋放new出來的緩衝區。

3、優化

在不修改原始碼的情況下,faac的記憶體佔用非常高,每路音訊在13M左右。如果多路音訊的話,記憶體將很快耗盡。

搜尋MAX_CHANNELS的定義,預設是6 和64,全部改成1(一般都是單聲道)。

重新編譯,執行,記憶體佔用降為2.5M左右。

編譯faac庫
cd faac-1.28
make clean
#./configure CXX=arm-hisiv300-linux-g++ CC=arm-hisiv300-linux-gcc --host=arm-linux --with-mp4v2=no 
./configure CXX=arm-hisiv300-linux-g++ CC=arm-hisiv300-linux-gcc --host=arm-linux --with-mp4v2=no CFLAGS="-mfpu=vfp -mfloat-abi=softfp" CXXFLAGS="-mfpu=vfp -mfloat-abi=softfp"
 
make
make install

編譯業務原始碼
OBJ_BIN=./aac_lib_v300/faac_v300
SRC_FILE=faac_test.cpp
arm-hisiv300-linux-gcc $SRC_FILE -o $OBJ_BIN -L/usr/local/lib -lfaac -I/usr/local/include -lsupc++ -mfpu=vfp -mfloat-abi=softfp

4、注意事項

 1)PCM規格,pcm_s16be(motorola PCM)   pcm_s16le(intel PCM), 兩者區別在於高低位,測試faac直接編碼pcm_s16le ok,不需要轉。
 2)faacEncEncode()編碼函式中的第三個引數是一次輸入的樣本數samplesInput,不是第二個引數輸入buffer的實際大小,而是通過faacEncOpen()獲取的。
 3)Faac是free的,但是音訊格式AAC是需要授權的。