心胸决定格局,眼界决定境界...

faad解码aac

// faad2.cpp : 定义控制台应用程序的入口点。
#include "stdafx.h"
#include <cassert>
#include <iostream>
#pragma comment(lib, "libfaad2.lib")
#include <stdio.h>  
#include <memory.h>
#include <string>
//#ifdef UNICODE
//typedef  std::wstring _tstring;
//#else
//typedef  std::string _tstring;
//#endif
#include <faad.h>  
#include "WavMaker1.h"
const unsigned int g_frmMaxLen = 1024 * 5;   
const unsigned int g_BufMaxLen = 1024 * 2048;//1024 * 1024
 
/** 
 * fetch one ADTS frame 
 * buffer 传递的是指针而不是指针的引用真是非常巧妙的一种方式.
 */  
int get_one_ADTS_frame(unsigned char* buffer, size_t buf_size, unsigned char* data ,size_t* data_size)  
{  
 size_t size = 0;  

 if(!buffer || !data || !data_size )  
 {
  assert(0);
  return -1;  
 }  
 while(1)  
 {  
  if(buf_size  < 7 )  
  {
   assert(0);
   return -1;  
  }  

  if((buffer[0] == 0xff) && ((buffer[1] & 0xf0) == 0xf0) )  
  {  
   // profile; 2 uimsbf
   // sampling_frequency_index; 4 uimsbf
   // private_bit; 1 bslbf
   // channel_configuration; 3 uimsbf
   // original/copy; 1 bslbf
   // home; 1 bslbf
   // copyright_identification_bit; 1 bslbf
   // copyright_identification_start; 1 bslbf
   // frame_length; 13 bslbf
   size |= ((buffer[3] & 0x03) <<11);     //high 2 bit  
   size |= buffer[4]<<3;                //middle 8 bit  
   size |= ((buffer[5] & 0xe0)>>5);        //low 3bit  
   break;  
  }  
  --buf_size;  
  ++buffer;  
 }  

 if(buf_size < size)  
 {  
  return -1;  
 }  

 memcpy(data, buffer, size);  
 *data_size = size;  

 return 0;  
}  
int _tmain(int argc, _TCHAR* argv[])
{  
 static unsigned char aacFrm[g_frmMaxLen];  //aac   最大帧长
 static unsigned char buffer[g_BufMaxLen];  //截取  aac文件的最大长度

 string src_file = "mp410.AAC";//输入文件	
 string dst_file = "mp410.wav";//输出文件
 FILE* ifile = NULL;  

 unsigned long samplerate = 0;  
 unsigned char channels  = 0;
 NeAACDecHandle decoder  = 0;  
 size_t data_size   = 0;  
 size_t size     = 0;  

 NeAACDecFrameInfo frame_info;
 memset(&frame_info, 0, sizeof(frame_info));
 unsigned char* input_data = buffer;  
 unsigned char* pcm_data  = NULL;  
 
 ifile   = fopen(src_file.c_str(), "rb"); //打开输入文件
 const char* p = dst_file.c_str();
 WavMaker   WavFile(p);
 if(!ifile)  
 {  
  assert(0);
  printf("source or destination file");  
  return -1;  
 }  


 //* 读取AAC文件.
 data_size = fread(buffer, 1, g_BufMaxLen, ifile);  //读取AAC文件长度  
 //* 打开解码器  
 decoder = NeAACDecOpen();
 //* 初始化解码器
 if(get_one_ADTS_frame(buffer, data_size, aacFrm, &size) < 0)  
 {
  assert(0);
  return -1;  
 } 
 NeAACDecInit(decoder, aacFrm, size, &samplerate, &channels);  
 printf("samplerate %d, channels %d\n", samplerate, channels);
 //* 初始化Wav结构
 //WAVEFORMATEX fmt;
 //fmt.wFormatTag = WAVE_FORMAT_PCM;
 //fmt.nChannels = channels;
 //fmt.nSamplesPerSec = samplerate;
 //fmt.wBitsPerSample = 16;
 //fmt.nBlockAlign = fmt.nChannels * fmt.wBitsPerSample /8;
 //fmt.nAvgBytesPerSec = fmt.nBlockAlign * samplerate;
 //fmt.cbSize = 0;
 //ofile.Init(fmt);
 //* 循环解码,写文件

 while(get_one_ADTS_frame(input_data, data_size, aacFrm, &size) == 0)  
 {  
	  pcm_data = (unsigned char*)NeAACDecDecode(decoder, &frame_info, aacFrm, size);   //解码信息在frame_info

	  if(frame_info.error > 0)  
	  {  
	   std::cout<<NeAACDecGetErrorMessage(frame_info.error)<<std::endl;
	  }  
	  else if(pcm_data && frame_info.samples > 0)  
	  {  
	   printf("frame info: bytesconsumed %d, channels %d, header_type %d\
		   object_type %d, samples %d, samplerate %d\n",   
		frame_info.bytesconsumed,   
		frame_info.channels, frame_info.header_type,   
		frame_info.object_type, frame_info.samples,   
		frame_info.samplerate);  
		WavFile.writebody(pcm_data, frame_info.samples * frame_info.channels  );//may be 有问题
	  }          
	  data_size -= size;  
	  input_data += size;  
 }      
	 NeAACDecClose(decoder);  
	 fclose(ifile);
	 WavFile.writeheader(frame_info.channels,frame_info.samplerate);
	 WavFile.closeFile();
 return 0;
}



 

 

 

posted @ 2014-04-15 15:02  WELEN  阅读(2596)  评论(0编辑  收藏  举报