注:本文为官方faac-1.28库学习笔记
1. 调用流程
对于编码AAC位流,以下调用序列是必须的:
- 为你需要的每个编码器实例调用faacEncOpen().
- 调用 faacEncGetCurrentConfiguration()获取配置; 修改参数后 调用 faacEncSetConfiguration() 设置配置;
- 只要还有样本需要编码,就调用faacEncEncode()来编码数据。编码器返回客户端提供的缓冲区中的位流数据;
- 一旦你用零样本的输入调用faacEncEncode(),刷新过程被启动;然后你可以只使用零样本输入调用faacEncEncode();faacEncEncode()将继续写入数据,直到所有音频样本都被编码。
- 一旦faacEncEncode()返回了写入的零字节,调用faacEncClose()来销毁这个编码器实例。
2. 初始化/反初始化
- 打开并初始化编码器的一个实例。
//sampleRate和numChannels为输入参数 inputSamples/maxOutputBytes为输出参数 faacEncHandle FAACAPI faacEncOpen(unsigned long sampleRate, //编码器输入数据的采样率 unsigned int numChannels,//编码器输入数据的通道数 unsigned long *inputSamples,//接收在每次调用中应该提供给faacEncEncode()的样本总数。 unsigned long *maxOutputBytes);//接收调用faacEncEncode()后输出缓冲区中可以包含的最大字节数。 返回值: 成功返回 faacEncHandle 句柄, 失败返回 NULL;
- 关闭 faacEncOpen 打开的句柄;
int FAACAPI faacEncClose(faacEncHandle hEncoder);
3. Encoder 配置
-
获取Encoder 配置
faacEncConfigurationPtr FAACAPI faacEncGetCurrentConfiguration(faacEncHandle hEncoder);
-
设置Encoder 配置
int FAACAPI faacEncSetConfiguration(faacEncHandle hEncoder,faacEncConfigurationPtr config);
-
faacEncConfiguration 结构体
typedef struct { void *ptr; char *name; }psymodellist_t; typedef struct faacEncConfiguration{ int version; /* config version */ char *name; /* library version */ char *copyright; /* copyright string */ unsigned int mpegVersion;/* MPEG version, 2 or 4 */ unsigned int aacObjectType;/* AAC object type */ unsigned int allowMidside; /* Allow mid/side coding */ unsigned int useLfe;/* 使用其中一个通道作为LFE通道 */ unsigned int useTns;/* 使用暂时噪声整形 */ unsigned long bitRate; /* bitrate / channel of AAC file */ unsigned int bandWidth;/* AAC file frequency bandwidth(带宽) */ unsigned long quantqual;/* Quantizer quality (量化器质量)*/ unsigned int outputFormat;/* Bitstream output format (0 = Raw; 1 = ADTS) */ psymodellist_t *psymodellist;/* psychoacoustic model list */ unsigned int psymodelidx; /* selected index in psymodellist */ /* 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 */ unsigned int inputFormat; int shortctl;/* block type enforcing (SHORTCTL_NORMAL/SHORTCTL_NOSHORT/SHORTCTL_NOLONG) */ /* 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;
4. 编码函数
int FAACAPI faacEncEncode(faacEncHandle hEncoder,
int32_t * inputBuffer, //包含要编码的音频样本。
/*inputBuffer中有效样本的数量,这应该是调用faacEncOpen()时在inputsamples中接收到的数量,
只要样本的数量是可用的。在没有输入样本的情况下调用faacEncEncode()后,将启动刷新过程。*/
unsigned int samplesInput,
unsigned char *outputBuffer,//指向接收比特流数据的缓冲区的指针; 大小至少是maxOutputBytes;
unsigned int bufferSize);
返回值:
负值表示失败,否则表示输出缓冲区中的vaid字节数。返回值为零并不表示失败
2022/2/19更新
追踪源码,先看句柄结构体
位置: libfaac/frame.h
typedef struct {
unsigned int numChannels; /* number of channels in AAC file AAC文件中的通道数*/
/* samplerate of AAC file AAC文件的样本*/
unsigned long sampleRate;
unsigned int sampleRateIdx;
unsigned int usedBytes;
/* frame number 帧数量 */
unsigned int frameNum;
unsigned int flushFrame;
/* Scalefactorband data */
SR_INFO *srInfo;
/* sample buffers of current next and next next frame 当前,下一帧和下下帧的缓冲区 */
double *sampleBuff[MAX_CHANNELS];
double *nextSampleBuff[MAX_CHANNELS];
double *next2SampleBuff[MAX_CHANNELS];
double *next3SampleBuff[MAX_CHANNELS];
double *ltpTimeBuff[MAX_CHANNELS];
/* Filterbank buffers Filterbank缓冲区*/
double *sin_window_long;
double *sin_window_short;
double *kbd_window_long;
double *kbd_window_short;
double *freqBuff[MAX_CHANNELS];
double *overlapBuff[MAX_CHANNELS];
double *msSpectrum[MAX_CHANNELS];
/* Channel and Coder data for all channels 所有通道的通道和编码器数据*/
CoderInfo coderInfo[MAX_CHANNELS];
ChannelInfo channelInfo[MAX_CHANNELS];
/* Psychoacoustics data */
PsyInfo psyInfo[MAX_CHANNELS];
GlobalPsyInfo gpsyInfo;
/* Configuration data 配置数据*/
faacEncConfiguration config;
psymodel_t *psymodel;
/* quantizer specific config 量化器的具体配置*/
AACQuantCfg aacquantCfg;
/* FFT Tables FFT表*/
FFT_Tables fft_tables;
/* output bits difference in average bitrate mode 平均比特率模式下的输出比特差 */
int bitDiff;
} faacEncStruct, *faacEncHandle;
//获取当前库版本号和版权信息; libfaac/frame.c中 ;结果存入二级指针中;
int FAACAPI faacEncGetVersion(char **faac_id_string,char **faac_copyright_string);
int FAACAPI faacEncGetDecoderSpecificInfo(faacEncHandle hEncoder,
unsigned char** ppBuffer,
unsigned long* pSizeOfDecoderSpecificInfo);
//获取当前配置 返回的是 &hEncoder->config
faacEncConfigurationPtr FAACAPI faacEncGetCurrentConfiguration(faacEncHandle hEncoder);
//设置配置 内部通过config填充hEncoder->config
int FAACAPI faacEncSetConfiguration (faacEncHandle hEncoder, faacEncConfigurationPtr config);
//分配faacEncStruct得到句柄,然后根据输入参数和固定参数初始化其中内容;最后返回句柄;
faacEncHandle FAACAPI faacEncOpen(unsigned long sampleRate,//采样率
unsigned int numChannels,//通道数量
unsigned long *inputSamples,//输入采样率
unsigned long *maxOutputBytes);//最大输出字节
//将inputBuffers pcm数据处理后写入AAC位流-> outputBuffer; 返回(位流)写入的字节数
int FAACAPI faacEncEncode(faacEncHandle hEncoder,//句柄
int32_t *inputBuffer, //输入的buffer数据
//inputBuffer中有效样本的数量 samplesInput= (inputBuffer字节数/ (nPCMBitSize / 8));
unsigned int samplesInput,
unsigned char *outputBuffer,//输出buffer数据
unsigned int bufferSize //输出buffer的大小
);
//先释放句柄中内容分配的内存,在释放句柄的内存;
int FAACAPI faacEncClose(faacEncHandle hEncoder);