关于faac的一点使用方式

在工做中使用faac时,不太理解,jni层调用时一直出错,发现最后是使用方式的问题

关于FAAC

FAAC是一个MPEG-4和MPEG-2的AAC编码器,其特性是:可移植性好,快速,支持LC/Main/LTP,经过Dream支持DRM,代码小相对于FFMPEG的AAC转码,FAAC实在是微乎其微,并且能够直接把代码加到工程里面编译,也可以使用静态库,而没有巨大的动态库的烦恼。
ide


下载安装

  • 直接按照官方文档所示,编译静态库以供咱们程序使用。(我没这么作,个中曲折错误不细数)
  • 把FAAC的代码抠出来,直接加到咱们的工程中去,或者抠出来编译一个静态库,简单暴力有效,须要的代码是libfaac和include两个目录下的全部文件(不包括子目录文件)。 目录文件列表以下所示:
    1. aacquant.c  
    2. aacquant.h  
    3. backpred.c  
    4. backpred.h  
    5. bitstream.c  
    6. bitstream.h  
    7. channels.c  
    8. channels.h  
    9. coder.h  
    10. faac.h  
    11. faaccfg.h  
    12. fft.c  
    13. fft.h  
    14. filtbank.c  
    15. filtbank.h  
    16. frame.c  
    17. frame.h  
    18. huffman.c  
    19. huffman.h  
    20. hufftab.h  
    21. ltp.c  
    22. ltp.h  
    23. midside.c  
    24. midside.h  
    25. psych.h  
    26. psychkni.c  
    27. tns.c  
    28. tns.h  
    29. util.c  
    30. util.h  
    31. version.h  
    aacquant.c aacquant.h backpred.c backpred.h bitstream.c bitstream.h channels.c channels.h coder.h faac.h faaccfg.h fft.c fft.h filtbank.c filtbank.h frame.c frame.h huffman.c huffman.h hufftab.h ltp.c ltp.h midside.c midside.h psych.h psychkni.c tns.c tns.h util.c util.h version.h
    强烈推荐使用第二种方法

转换流程示意图


主要的函数介绍函数

  1. faacEncHandle FAACAPI faacEncOpen(unsigned long sampleRate,  
  2.     unsigned int numChannels,  
  3.     unsigned long *inputSamples,  
  4.     unsigned long *maxOutputBytes);  
  5. //  描述 : 打开并初始化编码器  
  6. //  sampleRate : 编码输入信息的采样率  
  7. //  numChannels : 编码输入信息的通道数量,1-单声道 2-立体声  
  8. //  inputSamples : 编码后的数据长度  
  9. //  maxOutputBytes : 编码后的信息最大长度  
faacEncHandle FAACAPI faacEncOpen(unsigned long sampleRate, unsigned int numChannels, unsigned long *inputSamples, unsigned long *maxOutputBytes); // 描述 : 打开并初始化编码器 // sampleRate : 编码输入信息的采样率 // numChannels : 编码输入信息的通道数量,1-单声道 2-立体声 // inputSamples : 编码后的数据长度 // maxOutputBytes : 编码后的信息最大长度
  1. int FAACAPI faacEncClose(faacEncHandle hEncoder);  
  2. //  描述:关闭编码器  
  3. //  hEncoder : faacEncOpen返回的编码器句柄  
int FAACAPI faacEncClose(faacEncHandle hEncoder); // 描述:关闭编码器 // hEncoder : faacEncOpen返回的编码器句柄
  1. faacEncConfigurationPtr FAACAPI faacEncGetCurrentConfiguration(faacEncHandle hEncoder);  
  2. //  描述 :获取当前编码器的配置信息  
  3. //  hEncoder : faacEncOpen返回的编码器句柄  
faacEncConfigurationPtr FAACAPI faacEncGetCurrentConfiguration(faacEncHandle hEncoder); // 描述 :获取当前编码器的配置信息 // hEncoder : faacEncOpen返回的编码器句柄
  1. int FAACAPI faacEncSetConfiguration(faacEncHandle hEncoder, faacEncConfigurationPtr config);  
  2. //  描述 : 配置解码器的参数  
  3. //  hEncoder : faacEncOpen返回的编码器句柄  
  4. //  config : 编码器的配置信息  
int FAACAPI faacEncSetConfiguration(faacEncHandle hEncoder, faacEncConfigurationPtr config); // 描述 : 配置解码器的参数 // hEncoder : faacEncOpen返回的编码器句柄 // config : 编码器的配置信息
  1. int FAACAPI faacEncEncode(faacEncHandle hEncoder,   
  2.     int32_t * inputBuffer,   
  3.     unsigned int samplesInput,  
  4.     unsigned char *outputBuffer,  
  5.     unsigned int bufferSize);  
  6. //  描述 : 编码一桢信息  
  7. //  hEncoder : faacEncOpen返回的编码器句柄  
  8. //  inputBuffer : 输入信息缓冲区  
  9. //  samplesInput : faacEncOpen编码后的数据长度,即缓冲区长度  
  10. //  outputBuffer : 编码后输出信息缓冲区  
  11. //  bufferSize : 输出信息长度  
int FAACAPI faacEncEncode(faacEncHandle hEncoder, int32_t * inputBuffer, unsigned int samplesInput, unsigned char *outputBuffer, unsigned int bufferSize); // 描述 : 编码一桢信息 // hEncoder : faacEncOpen返回的编码器句柄 // inputBuffer : 输入信息缓冲区 // samplesInput : faacEncOpen编码后的数据长度,即缓冲区长度 // outputBuffer : 编码后输出信息缓冲区 // bufferSize : 输出信息长度
  1. int FAACAPI faacEncGetVersion(char **faac_id_string, char **faac_copyright_string);  
  2. //  描述 : 获取FAAC的版本信息,用以参考做用,非必须API  
  3. //  faac_id_string : faac的版本号  
  4. //  faac_copyright_string : 版权信息  
int FAACAPI faacEncGetVersion(char **faac_id_string, char **faac_copyright_string); // 描述 : 获取FAAC的版本信息,用以参考做用,非必须API // faac_id_string : faac的版本号 // faac_copyright_string : 版权信息

代码示例

代码的工做流程是:
  1. 打开输入输出文件
  2. 使用faacEncOpen打开编码器引擎
  3. 使用faacEncGetCurrentConfiguratio获取编码器配置
  4. 配置编码器参数
  5. 使用faacEncSetConfiguration设置编码器配置
  6. 读取一桢输入数据
  7. 使用faacEncEncode编码帧数据
  8. 写入编码数据到输出文件
  9. 使用faacEncClose关闭编码引擎
  1. //    
  2. //  faac example code  
  3. //  PCM to ACC    
  4. //    
  5. //  Created by arbboter on 15/1/26.    
  6. //  Copyright (c) 2015年 arbboter. All rights reserved.    
  7. //   
  8. #include "faac.h"  
  9. #include <stdio.h>  
  10.   
  11. int main()  
  12. {  
  13.     // 定义别名  
  14.     typedef unsigned char   BYTE;  
  15.   
  16.     unsigned long   nSampleRate = 44100;  
  17.     unsigned int    nChannels = 2;  
  18.     unsigned int    nPCMBitSize = 16;  
  19.     unsigned long   nInputSamples = 0;  
  20.     unsigned long   nMaxOutputBytes = 0;  
  21.     faacEncHandle   hEncoder = {0};  
  22.   
  23.     // 设置输入输出文件  
  24.     FILE* fpIn = fopen("Beyond.pcm""rb");  
  25.     FILE* fpOut = fopen("Beyond.aac""wb");  
  26.   
  27.     if(fpIn==NULL || fpOut==NULL)  
  28.     {  
  29.         printf("打开文件失败!\n");  
  30.         return -1;  
  31.     }  
  32.   
  33.     // 打开faac编码器引擎  
  34.     hEncoder = faacEncOpen(nSampleRate, nChannels, &nInputSamples, &nMaxOutputBytes);  
  35.     if(hEncoder == NULL)  
  36.     {  
  37.         printf("打开faac编码器引擎失败!\n");  
  38.         return -1;  
  39.     }  
  40.   
  41.     // 分配内存信息  
  42.     int     nPCMBufferSize = nInputSamples*nPCMBitSize/8;  
  43.     BYTE*   pbPCMBuffer = new BYTE[nPCMBufferSize];  
  44.     BYTE*   pbAACBuffer = new BYTE[nMaxOutputBytes];  
  45.   
  46.     // 获取当前编码器信息  
  47.     faacEncConfigurationPtr pConfiguration = {0};  
  48.     pConfiguration = faacEncGetCurrentConfiguration(hEncoder);  
  49.   
  50.     // 设置编码配置信息  
  51.     /* 
  52.         PCM Sample Input Format 
  53.         0   FAAC_INPUT_NULL         invalid, signifies a misconfigured config 
  54.         1   FAAC_INPUT_16BIT        native endian 16bit 
  55.         2   FAAC_INPUT_24BIT        native endian 24bit in 24 bits      (not implemented) 
  56.         3   FAAC_INPUT_32BIT        native endian 24bit in 32 bits      (DEFAULT) 
  57.         4   FAAC_INPUT_FLOAT        32bit floating point 
  58.     */  
  59.     pConfiguration->inputFormat = FAAC_INPUT_16BIT;  
  60.   
  61.     // 0 = Raw; 1 = ADTS  
  62.     pConfiguration->outputFormat = 1;  
  63.   
  64.     // AAC object types   
  65.     //#define MAIN 1  
  66.     //#define LOW  2  
  67.     //#define SSR  3  
  68.     //#define LTP  4  
  69.     pConfiguration->aacObjectType = LOW;  
  70.     pConfiguration->allowMidside = 0;  
  71.     pConfiguration->useLfe = 0;  
  72.     pConfiguration->bitRate = 48000;  
  73.     pConfiguration->bandWidth = 32000;  
  74.   
  75.     // 其余的参数不知道怎么配置,毕竟对音频不熟  
  76.     // 不过当前的设置能够实现转换,不过声音好像有一丢丢怪异  
  77.     // 这一块的配置信息很重要,错了会致使转码失败,而后你觉得代码其余地方错了  
  78.   
  79.     // 重置编码器的配置信息  
  80.     faacEncSetConfiguration(hEncoder, pConfiguration);  
  81.   
  82.     size_t nRet = 0;  
  83.   
  84.     printf("数据转换中:        ");  
  85.     int i = 0;  
  86.     while( (nRet = fread(pbPCMBuffer, 1, nPCMBufferSize, fpIn)) > 0)  
  87.     {  
  88.         printf("\b\b\b\b\b\b\b\b%-8d", ++i);  
  89.         nInputSamples = nRet / (nPCMBitSize/8);  
  90.   
  91.         // 编码  
  92.         nRet = faacEncEncode(hEncoder, (int*) pbPCMBuffer, nInputSamples, pbAACBuffer, nMaxOutputBytes);  
  93.   
  94.         // 写入转码后的数据  
  95.         fwrite(pbAACBuffer, 1, nRet, fpOut);  
  96.     }  
  97.   
  98.     // 扫尾工做  
  99.     faacEncClose(hEncoder);  
  100.     fclose(fpOut);  
  101.     fclose(fpIn);  
  102.   
  103.     delete[] pbAACBuffer;  
  104.     delete[] pbPCMBuffer;  
  105.       
  106.     return 0;  
  107. }  
// // faac example code // PCM to ACC // // Created by arbboter on 15/1/26. // Copyright (c) 2015年 arbboter. All rights reserved. // #include "faac.h" #include <stdio.h> int main() { // 定义别名 typedef unsigned char BYTE; unsigned long nSampleRate = 44100; unsigned int nChannels = 2; unsigned int nPCMBitSize = 16; unsigned long nInputSamples = 0; unsigned long nMaxOutputBytes = 0; faacEncHandle hEncoder = {0}; // 设置输入输出文件 FILE* fpIn = fopen("Beyond.pcm", "rb"); FILE* fpOut = fopen("Beyond.aac", "wb"); if(fpIn==NULL || fpOut==NULL) { printf("打开文件失败!\n"); return -1; } // 打开faac编码器引擎 hEncoder = faacEncOpen(nSampleRate, nChannels, &nInputSamples, &nMaxOutputBytes); if(hEncoder == NULL) { printf("打开faac编码器引擎失败!\n"); return -1; } // 分配内存信息 int nPCMBufferSize = nInputSamples*nPCMBitSize/8; BYTE* pbPCMBuffer = new BYTE[nPCMBufferSize]; BYTE* pbAACBuffer = new BYTE[nMaxOutputBytes]; // 获取当前编码器信息 faacEncConfigurationPtr pConfiguration = {0}; pConfiguration = faacEncGetCurrentConfiguration(hEncoder); // 设置编码配置信息 /* PCM Sample Input Format 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 */ pConfiguration->inputFormat = FAAC_INPUT_16BIT; // 0 = Raw; 1 = ADTS pConfiguration->outputFormat = 1; // AAC object types //#define MAIN 1 //#define LOW 2 //#define SSR 3 //#define LTP 4 pConfiguration->aacObjectType = LOW; pConfiguration->allowMidside = 0; pConfiguration->useLfe = 0; pConfiguration->bitRate = 48000; pConfiguration->bandWidth = 32000; // 其余的参数不知道怎么配置,毕竟对音频不熟 // 不过当前的设置能够实现转换,不过声音好像有一丢丢怪异 // 这一块的配置信息很重要,错了会致使转码失败,而后你觉得代码其余地方错了 // 重置编码器的配置信息 faacEncSetConfiguration(hEncoder, pConfiguration); size_t nRet = 0; printf("数据转换中: "); int i = 0; while( (nRet = fread(pbPCMBuffer, 1, nPCMBufferSize, fpIn)) > 0) { printf("\b\b\b\b\b\b\b\b%-8d", ++i); nInputSamples = nRet / (nPCMBitSize/8); // 编码 nRet = faacEncEncode(hEncoder, (int*) pbPCMBuffer, nInputSamples, pbAACBuffer, nMaxOutputBytes); // 写入转码后的数据 fwrite(pbAACBuffer, 1, nRet, fpOut); } // 扫尾工做 faacEncClose(hEncoder); fclose(fpOut); fclose(fpIn); delete[] pbAACBuffer; delete[] pbPCMBuffer; return 0; }
编码器的参数设置,能够找正确的解码例子照例修改或者问专业人士吧,若是出错了的话。