AAC--使用faad解码AAC

faad库实现aac编解码流程:

自定义一个结构体:
typedef struct 
{
	long bytes_in_buffer;//当前缓存的待处理的总数据量
	long bytes_consumed;//当前缓存中已经消耗数据量
	long file_offset;//当前处理到的位置(相对于文件的偏移)
	unsigned char *buffer;	//缓存 准备足够大	malloc(FAAD_MIN_STREAMSIZE*MAX_CHANNELS);
	int  at_eof;//文件结束标志
	FILE *infile;//输入文件操作句柄
	FILE *pOutputFile;//输出文件句柄
} aac_buffer;

#define FAAD_MIN_STREAMSIZE 768 /* 6144 bits/channel */
#define  MAX_CHANNELS		(8)


1、创建解码器
NeAACDecHandle NEAACDECAPI NeAACDecOpen(void);
 
2、配置解码器 //对于原始AAC数据是必须的 否则解码器不知道音频封装信息
//对于ADTS封装的AAC 不需要设置 解码器可以从视频数据中获取
NeAACDecConfigurationPtr NEAACDECAPI NeAACDecGetCurrentConfiguration(NeAACDecHandle hDecoder);
//输入的参数为第一步创建的解码器的句柄,返回为解码器配置参数的结构体的指针。获取失败则会返回为空。

设置参数如下:
conf->defObjectType = LC;//类型
conf->defSampleRate = sampleRate;//采样率
conf->outputFormat = FAAD_FMT_16BIT;//保存音频的位数
conf->dontUpSampleImplicitSBR = 1;//SBR标志

unsigned char NEAACDECAPI NeAACDecSetConfiguration(NeAACDecHandle hDecoder,
                                                   NeAACDecConfigurationPtr config);
//函数中,第一个参数为解码器句柄,第二个为我们的的配置结构体的指针对象。返回值为0时代表配置失败。

//数据初始化
long NEAACDECAPI NeAACDecInit(NeAACDecHandle hDecoder,    //解码器句柄
                              unsigned char *buffer,        //输入数据的指针
                              unsigned long buffer_size,    //  输入数据的长度
                              unsigned long *samplerate,    //保存从aac数据中获取的编码的采样率
                              unsigned char *channels);    //保存从aac数据中获取的编码的通道数
//返回非0则代表成功。此方法只需要在解码数据前调用一次,无需重复调用。其中输入的数据最好多余一个aac数据包,以便正确解析数据。




解码AAC数据//每次输入一帧ADTS 解码为PCM   利用同步数据为0xfff来分割aac数据帧
void* NEAACDECAPI NeAACDecDecode(NeAACDecHandle hDecoder,      //解码器句柄
                                 NeAACDecFrameInfo *hInfo,      //解码frame的信息
                                 unsigned char *buffer,      //需要解码的数据指针
                                 unsigned long buffer_size);    //需要解码的数据的长度
//NeAACDecFrameInfo *hInfo.error>0表示解码失败
//我们可以根据第二个参数返回的 unsigned long samples;unsigned char channels;两个属性进行手动计算PCM数据的大小,然后从返回指针的起始地址读取相应的字节数,这时候此段内存中保存的数据即为解码的PCM数据。

关闭解码器:
void NEAACDECAPI NeAACDecClose(NeAACDecHandle hDecoder);


音频编解码基础(wav/aac/pcma/pcmu)
此人的函数:

do{
		//抛弃已经使用过的数据 将buf中用掉的长度移除
		advance_buffer(&g_AacBuffer, lOffset);
		//空的缓存填充新的数据---为buf补充用掉的长度使之回到最初的长度
		fill_buffer(&g_AacBuffer);
		lOffset=0;
		while(1)
		{
			int iConsumNum=0;
			int iRet = getADTSframe(g_AacBuffer.buffer+lOffset, g_AacBuffer.bytes_into_buffer-lOffset,&iConsumNum, pTempBuffer ,&(iFrameSize));
			if(iRet == 0)//找到一个frame
			{
				lOffset+=iConsumNum;
				AdtsHeadInfo stHeadInfo;
				if(ParserAdtsHead(pTempBuffer ,iFrameSize,&stHeadInfo))//解析一帧提取一帧的头的几个数据
					printf("Profile:%02d\tChans:%02d\tSampleRate:%05d\tHeadSize:%01d\tFrameSize:%06d\t\n",stHeadInfo.iProfile,stHeadInfo.iChans,stHeadInfo.iSampleRate,stHeadInfo.iHeadLen,stHeadInfo.iFrameSize);
			}
			else if(iRet == 1){//buf长度不够一个frame
				lOffset+=iConsumNum;
				break;
			}
		}
	}while(没有读到文件结尾);
发布了81 篇原创文章 · 获赞 1 · 访问量 2878

猜你喜欢

转载自blog.csdn.net/qq_42024067/article/details/104580227