调试成功并导入项目的faad2解码aac示例
包括Test.c和封装好的接口,解决解码后采样频率和通道数问题
下载链接:
//---------------------------------------------------------------------------------------------------------//
注意事项:
1,解码aac-解决采样频率和通道数不对的问题。
//防止采样频率加倍
NeAACDecConfigurationPtr conf = NeAACDecGetCurrentConfiguration(decoder);
conf->dontUpSampleImplicitSBR = 1;
NeAACDecSetConfiguration(decoder, conf);
//从双声道的数据中提取单通道
for(i=0,j=0; i<4096 && j<2048; i+=4, j+=2)
{
frame_mono[j]=pcm_data[i];
frame_mono[j+1]=pcm_data[i+1];
}
//---------------------------------------------------------------------------------------------------------//
后来跟踪源码才发现 FAAD的NeAACDecInit() 源代码如下:
-
long NEAACDECAPI NeAACDecInit(NeAACDecHandle hpDecoder,
-
unsignedchar *buffer,
-
unsignedlong buffer_size,
-
unsignedlong *samplerate,
-
unsignedchar *channels)
-
{
-
-
#if (defined(PS_DEC) || defined(DRM_PS))
-
-
if (*channels == 1)
-
{
-
-
*channels = 2;
-
}
-
#endif
-
-
hDecoder->channelConfiguration = *channels;
-
-
#ifdef SBR_DEC
-
-
if (*samplerate <= 24000 && (hDecoder->config.dontUpSampleImplicitSBR == 0))
-
{
-
*samplerate *= 2;
-
hDecoder->forceUpSampling = 1;
-
}
-
else if (*samplerate > 24000 && (hDecoder->config.dontUpSampleImplicitSBR == 0)) {
-
hDecoder->downSampledSBR = 1;
-
}
-
#endif
-
}
上面那些宏,在源代码中貌似已经定死了,不是通过条件编译生成的,
也就是 PS_DEC 和 SBR_DEC是define过的...也不是通过./configure 的时候生成的...
再仔细看上面代码的if语句
if (*samplerate <= 24000 && (hDecoder->config.dontUpSampleImplicitSBR == 0))
只要让 hDecoder->config.dontUpSampleImplicitSBR 不为0 不就OK吗?
//---------------------------------------------------------------------------------------------------------//
下面为简单Test示例
#include
#include
#include
#include
#include
#include
#include
#include"faad.h"
#define FRAME_MAX_LEN 1024*5
#define BUFFER_MAX_LEN 1024*1024
static char* file_buf;
static int file_size;
static int fd_input;
int open_file(char* file_input)
{
fd_input=open(file_input, O_RDONLY);
if(fd_input<=0)
{
fprintf(stderr, "open %s fail\n", file_input);
return -1;
}
return 0;
}
int close_file(void)
{
if(fd_input>0)
{
close(fd_input);
}
return 0;
}
int file_mem_alloc(void)
{
struct stat file_st;
if(fstat(fd_input, &file_st)<0)
{
perror("get file size fail\n");
return -1;
}
file_size=file_st.st_size;
printf("input file size: %d\n", file_size);
file_buf=(char*)malloc(file_size);
if(file_buf==NULL)
{
printf("file mem malloc fail\n");
return -1;
}
return 0;
}
int read_file_to_mem(void)
{
int len;
int bytes;
len=file_size;
bytes=0;
do
{
bytes+=read(fd_input, file_buf + bytes, len - bytes);
}while(bytes
return 0;
}
int file_mem_free(void)
{
free(file_buf);
return 0;
}
void show_usage()
{
printf("usage\nfaaddec src_file dst_file");
}
int get_one_ADTS_frame(unsigned char* buffer, int buf_size, unsigned char* data ,int* data_size)
{
int size = 0;
if(!buffer || !data || !data_size )
{
return -1;
}
while(1)
{
if(buf_size < 7 )
{
return -1;
}
if((buffer[0] == 0xff) && ((buffer[1] & 0xf0) == 0xf0) )
{
size |= (((buffer[3] & 0x03)) <<11); //high 2 bit
size |= (buffer[4]<<3); //middle 8 bit
size |= ((buffer[5] & 0xe0)>>5); //low 3bit
printf("len1=%x\n", (buffer[3] & 0x03));
printf("len2=%x\n", buffer[4]);
printf("len3=%x\n", (buffer[5] & 0xe0)>>5);
printf("size=%d\r\n", (int)size);
break;
}
--buf_size;
++buffer;
}
if(buf_size < size)
{
return -1;
}
memcpy(data, buffer, size);
*data_size = size;
return 0;
}
int main(int argc, char* argv[])
{
static unsigned char frame[FRAME_MAX_LEN];
static unsigned char frame_mono[FRAME_MAX_LEN];
char* fin_name;
char* fout_name;
int fout=0;
int i;
int j;
unsigned long samplerate;
unsigned char channels;
NeAACDecHandle decoder = 0;
int data_size = 0;
int size = 0;
NeAACDecFrameInfo frame_info;
unsigned char* input_data;
unsigned char* pcm_data = NULL;
//analyse parameter
if(argc<3)
{
show_usage();
return -1;
}
fin_name=argv[1];
fout_name=argv[2];
fout = open(fout_name, O_RDWR|O_CREAT|O_TRUNC);
if(!fout)
{
printf("open %s fail\n", fout_name);
return -1;
}
open_file(fin_name);
file_mem_alloc();
read_file_to_mem();
//open decoder
decoder = NeAACDecOpen();
if(get_one_ADTS_frame((unsigned char*)file_buf, file_size, frame, &size) < 0)
{
printf("can't get one ADTS frame\n");
return -1;
}
//防止采样频率加倍
#if 1
NeAACDecConfigurationPtr conf = NeAACDecGetCurrentConfiguration(decoder);
conf->dontUpSampleImplicitSBR = 1;
NeAACDecSetConfiguration(decoder, conf);
#endif
//initialize decoder
NeAACDecInit(decoder, frame, size, &samplerate, &channels);
printf("samplerate %ld, channels %d\n", samplerate, channels);
//return 0;
input_data=(unsigned char*)file_buf;
data_size=file_size;
while(get_one_ADTS_frame(input_data, data_size, frame, &size) == 0)
{
printf("frame size %d\n", (int)size);
//decode ADTS frame
pcm_data = (unsigned char*)NeAACDecDecode(decoder, &frame_info, frame, size);
if(frame_info.error > 0)
{
printf("%s\n",NeAACDecGetErrorMessage(frame_info.error));
}
else if(pcm_data && frame_info.samples > 0)
{
printf("frame info: bytesconsumed %ld, channels %d, header_type %d\
object_type %d, samples %ld, samplerate %ld\n",
frame_info.bytesconsumed,
frame_info.channels, frame_info.header_type,
frame_info.object_type, frame_info.samples,
frame_info.samplerate);
//从双声道的数据中提取单通道
for(i=0,j=0; i<4096 && j<2048; i+=4, j+=2)
{
frame_mono[j]=pcm_data[i];
frame_mono[j+1]=pcm_data[i+1];
}
write(fout, frame_mono, frame_info.samples);
sync();
}
data_size -= size;
input_data += size;
}
NeAACDecClose(decoder);
file_mem_free();
close_file();
close(fout);
return 0;
}
阅读(2401) | 评论(0) | 转发(0) |