编译
Linux平台编译需要注意平台的兼容性,一些.a文件是32位的,所以在64位系统下编译就需要-m32 flags;
编译的Makefile文件中修改:
CFLAGS = -m32 -Wall -W -Wstrict-prototypes -Wmissing-prototypes -g
LDFLAGS += -m32 -LFloatFRlib/lib/$(UNAME) -lFloatFR -Llib/linux -Laudiolib/lib/$(UNAME) -laudio -Llib/linux -Llibisomediafile/lib/$(UNAME) -lisomediafile
Linux平台下直接
make clean
make
Windows平台直接用visual studio打开工程编译即可。
运行
Linux平台
不加error pattern方式:
./enhAacPlusDec /home/gg/Develope/26410-d00/media/File2.mp4 /home/gg/Develope/26410-d00/media/File2.wav def
有error pattern模式:
./enhAacPlusDec /home/gg/Develope/26410-d00/media/File2.mp4 /home/gg/Develope/26410-d00/media/File2_err.wav def /home/gg/Develope/26410-d00/media/err.txt
windows平台同样可以在cmd里如上方式运行,
或者visual studio环境里的命令行参数加上参数,直接运行就可以。
这里提供了Visual Studio10和linux编译工程下载:
http://download.csdn.net/detail/mandagod/9724999
Demo程序的修改:
对于AAC音频丢帧或者是坏掉的音频帧,可以以来于前后的解码帧,容错丢掉的音频帧解码,如下方式修改:
下面是从error pattern里读取标志位,1是正常帧,0是有错误的帧表示;
/* Reading error pattern from file (not instrumented) */
frameOk = ReadErrorPatternFile(pErrorPatternFile);
if (frameOk) {
/* Reading bitstream data from file (not instrumented) */
endOfFile = CBitstreamFillBufferAU(hBitBuf,inputFile);
} else {
endOfFile = CBitstreamFillBufferAU1(hBitBuf,inputFile);
}
当碰到了error帧,回退到last good frame的位置,依赖之前的帧数据,补偿解码丢失的音频帧数据。
如上面error pattern和无error pattern 两种方式运行,解码出来的.wav文件波形上比较很相近。例如RTP或者其他传输协议中对于紧急或者避免以重传的方式获取音频帧,这种解码的方式很快就能补偿,对于连麦这种场合很有用处。
对于单个音频帧丢失或者坏掉,隐藏插入方式恢复解码,最后一个好的帧和第一个好的帧之间创建频谱数据给丢失帧做补偿处理。
对于多个丢失或者坏掉的帧,隐藏插入方式恢复解码,以最后一个有效帧做轻微修改渐出方式处理,直到遇到一个有效帧出现,以这个有效帧做渐入处理。详细的实现可以查看解码的源码实现。
//unsigned char readbuf_last[4096];
unsigned int cbValid_last;
/*
The function reads the bitstream from a MPEG-4 file and stores the bitstream
in the input buffer. The input buffer is filled with one AU.
return: 1 if end of file has been reached
*/
static int CBitstreamFillBufferAU(HANDLE_BIT_BUF hBitBuf, /*!< pointer to current data in bitstream */
FileWrapperPtr transport
)
{
unsigned int cbValid;
unsigned int i;
int ErrorStatus = 0;
unsigned char readbuf[4096];
/* read bitstream */
ErrorStatus = FileWrapper_Read(transport, readbuf, 4096, &cbValid);
cbValid_last = cbValid;
for (i=0; i<cbValid; i++) {
//readbuf_last[i] = readbuf[i];
WriteBits(hBitBuf,readbuf[i],8);
}
return ErrorStatus;
}
static int CBitstreamFillBufferAU1(HANDLE_BIT_BUF hBitBuf, /*!< pointer to current data in bitstream */
FileWrapperPtr transport
)
{
unsigned int cbValid;
unsigned int i;
int ErrorStatus = 0;
unsigned char readbuf[4096];
/* read bitstream */
ErrorStatus = FileWrapper_Read(transport, readbuf, 4096, &cbValid);
//for (i=0; i<cbValid; i++) {
/*
readbuf[i] = '0';
WriteBits(hBitBuf,readbuf[i],8); // not ok, lost frame can't decode, err code 5
*/
//WriteBits(hBitBuf,readbuf_last[i],8); // not ok, next of the lost frame can't decode, err code 5
//not write // not ok, next of the lost frame can't decode, err code 5
//}
WindBitBufferBidirectional(hBitBuf, -cbValid_last*8); // rewind to last good frame position
return ErrorStatus;
}