Chinaunix首页 | 论坛 | 博客
  • 博客访问: 51772
  • 博文数量: 14
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 152
  • 用 户 组: 普通用户
  • 注册时间: 2017-07-19 11:43
个人简介

音视频 流媒体 号码:15721098449 CSDN:http://blog.csdn.net/yuanchunsi

文章分类

全部博文(14)

文章存档

2017年(14)

我的朋友

分类: C/C++

2017-08-01 17:48:24

调试成功并导入项目的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() 源代码如下:

  1. long NEAACDECAPI NeAACDecInit(NeAACDecHandle hpDecoder,  
  2.                               unsignedchar *buffer,  
  3.                               unsignedlong buffer_size,  
  4.                               unsignedlong *samplerate,  
  5.                               unsignedchar *channels)  
  6. {  
  7.   
  8. #if (defined(PS_DEC) || defined(DRM_PS))  
  9. /* check if we have a mono file */  
  10. if (*channels == 1)  
  11. {  
  12.      /* upMatrix to 2 channels for implicit signalling of PS */  
  13.      *channels = 2;  // 这里channels改变为2,why?  
  14. }  
  15. #endif  
  16.   
  17. hDecoder->channelConfiguration = *channels;  
  18.   
  19. #ifdef SBR_DEC  
  20. /* implicit signalling */  
  21. if (*samplerate <= 24000 && (hDecoder->config.dontUpSampleImplicitSBR == 0))  
  22. {  
  23.     *samplerate *= 2;    // samplerate 变为32000  
  24.     hDecoder->forceUpSampling = 1;  
  25. }   
  1. else if (*samplerate > 24000 && (hDecoder->config.dontUpSampleImplicitSBR == 0)) {  
  2.      hDecoder->downSampledSBR = 1;  
  3. }  
  4. #endif  
  5. }  

  上面那些宏,在源代码中貌似已经定死了,不是通过条件编译生成的,

也就是 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) |
给主人留下些什么吧!~~