cfaad.cpp
来自「faac-1.25.rar音频编解码器demo」· C++ 代码 · 共 808 行 · 第 1/2 页
CPP
808 行
void Cfaad::setFaadCfg(faacDecHandle hDecoder, CMyDecCfg Cfg)
{
faacDecConfigurationPtr config=faacDecGetCurrentConfiguration(hDecoder);
if(!Cfg.DefaultCfg)
{
config->defObjectType=Cfg.DecCfg.defObjectType;
config->outputFormat=Cfg.DecCfg.outputFormat;
config->defSampleRate=Cfg.DecCfg.defSampleRate;
config->downMatrix=Cfg.DecCfg.downMatrix;
config->useOldADTSFormat=Cfg.DecCfg.useOldADTSFormat;
config->dontUpSampleImplicitSBR=1;
}
else
{
config->defObjectType=LC;
config->outputFormat=FAAD_FMT_16BIT;
config->defSampleRate=44100;
config->downMatrix=0;
config->useOldADTSFormat=0;
config->dontUpSampleImplicitSBR=1;
}
faacDecSetConfiguration(hDecoder, config);
}
// -----------------------------------------------------------------------------------------------
void Cfaad::setDefaultFaadCfg(faacDecHandle hDecoder, BOOL showDlg)
{
if(showDlg && ShowDlg4RawAAC)
ShowDlg4RawAAC();
CMyDecCfg Cfg(false);
setFaadCfg(hDecoder,Cfg);
}
// -----------------------------------------------------------------------------------------------
void Cfaad::DisplayError(char *ProcName, char *str)
{
MYINPUT *mi;
char buf[100]="";
GlobalUnlock(hInput); // it wasn't done in getInfos()
GLOBALLOCK(mi,hInput,MYINPUT,return);
if(ProcName && *ProcName)
sprintf(buf,"%s: ", ProcName);
if(str && *str)
strcat(buf,str);
if(*buf && str)
MessageBox(0, buf, APP_NAME " plugin", MB_OK|MB_ICONSTOP);
mi->bytes_into_buffer=-1;
GlobalUnlock(hInput);
}
// *********************************************************************************************
HANDLE Cfaad::getInfos(LPSTR lpstrFilename)
{
MYINPUT *mi;
// test tags
//CMyDecCfg cfg; cfg.Tag.ReadMp4Tag(lpstrFilename);
//CMyDecCfg cfg; cfg.Tag.ReadAacTag(lpstrFilename);
GLOBALLOCK(mi,hInput,MYINPUT,return NULL);
// mi->IsAAC=strcmpi(lpstrFilename+lstrlen(lpstrFilename)-4,".aac")==0;
if((mi->IsMP4=IsMP4(lpstrFilename))==-1)
return ERROR_getInfos("Error opening file");
if(mi->IsMP4) // MP4 file ---------------------------------------------------------------------
{
MP4Duration length;
unsigned __int32 buffer_size;
DWORD timeScale;
BYTE sf;
mp4AudioSpecificConfig mp4ASC;
if(!(mi->mp4File=MP4Read(lpstrFilename, 0)))
return ERROR_getInfos("Error opening file");
if((mi->track=GetAACTrack(mi->mp4File))<0)
return ERROR_getInfos(0); //"Unable to find correct AAC sound track");
if(!(mi->hDecoder=faacDecOpen()))
return ERROR_getInfos("Error initializing decoder library");
MP4GetTrackESConfiguration(mi->mp4File, mi->track, (unsigned __int8 **)&mi->buffer, &buffer_size);
if(!mi->buffer)
return ERROR_getInfos("MP4GetTrackESConfiguration()");
AudioSpecificConfig(mi->buffer, buffer_size, &mp4ASC);
timeScale = mp4ASC.samplingFrequency;
mi->Channels=mp4ASC.channelsConfiguration;
sf = mp4ASC.samplingFrequencyIndex;
mi->type = mp4ASC.objectTypeIndex;
// mi->SBR=mp4ASC.sbr_present_flag;
if(faacDecInit2(mi->hDecoder, mi->buffer, buffer_size, &mi->Samprate, &mi->Channels) < 0)
return ERROR_getInfos("Error initializing decoder library");
FREE_ARRAY(mi->buffer);
length=MP4GetTrackDuration(mi->mp4File, mi->track);
mi->len_ms=(DWORD)MP4ConvertFromTrackDuration(mi->mp4File, mi->track, length, MP4_MSECS_TIME_SCALE);
mi->file_info.bitrate=MP4GetTrackBitRate(mi->mp4File, mi->track);
mi->file_info.version=MP4GetTrackAudioType(mi->mp4File, mi->track)==MP4_MPEG4_AUDIO_TYPE ? 4 : 2;
mi->numSamples=MP4GetTrackNumberOfSamples(mi->mp4File, mi->track);
mi->sampleId=1;
mi->IsSeekable=true;
mi->LockSeeking=!mi->IsSeekable;
}
else // AAC file ------------------------------------------------------------------------------
{
DWORD read,
tmp;
BYTE Channels4Raw=0;
if(!(mi->aacFile=fopen(lpstrFilename,"rb")))
return ERROR_getInfos("Error opening file");
// use bufferized stream
setvbuf(mi->aacFile,NULL,_IOFBF,32767);
// get size of file
fseek(mi->aacFile, 0, SEEK_END);
mi->src_size=ftell(mi->aacFile);
fseek(mi->aacFile, 0, SEEK_SET);
if(!(mi->buffer=(BYTE *)malloc(FAAD_STREAMSIZE)))
return ERROR_getInfos("Memory allocation error: mi->buffer");
tmp=mi->src_size<FAAD_STREAMSIZE ? mi->src_size : FAAD_STREAMSIZE;
read=fread(mi->buffer, 1, tmp, mi->aacFile);
if(read==tmp)
{
mi->bytes_read=read;
mi->bytes_into_buffer=read;
}
else
return ERROR_getInfos("Read failed!");
// skip Tag
long tagsize;
if(tagsize=id3v2_TagSize(mi->buffer))
{
if(tagsize>(long)mi->src_size)
ERROR_getInfos("Corrupt stream!");
if(tagsize<mi->bytes_into_buffer)
{
mi->bytes_into_buffer-=tagsize;
memcpy(mi->buffer,mi->buffer+tagsize,mi->bytes_into_buffer);
}
else
{
mi->bytes_read=tagsize;
mi->bytes_into_buffer=0;
if(tagsize>mi->bytes_into_buffer)
fseek(mi->aacFile, tagsize, SEEK_SET);
}
if(mi->src_size<mi->bytes_read+FAAD_STREAMSIZE-mi->bytes_into_buffer)
tmp=mi->src_size-mi->bytes_read;
else
tmp=FAAD_STREAMSIZE-mi->bytes_into_buffer;
read=fread(mi->buffer+mi->bytes_into_buffer, 1, tmp, mi->aacFile);
if(read==tmp)
{
mi->bytes_read+=read;
mi->bytes_into_buffer+=read;
}
else
ERROR_getInfos("Read failed!");
}
if(get_AAC_format(lpstrFilename, &mi->file_info, &mi->seek_table, &mi->seek_table_length, 0))
ERROR_getInfos("get_AAC_format()");
mi->IsSeekable=mi->file_info.headertype==ADTS && mi->seek_table && mi->seek_table_length>0;
mi->LockSeeking=!mi->IsSeekable;
/*
aac_buffer b;
float fLength;
DWORD headertype;
b.infile=mi->aacFile;
b.buffer=mi->buffer;
b.bytes_into_buffer=read;
b.bytes_consumed=mi->bytes_consumed;
b.file_offset=0;
b.at_eof=(read!=tmp) ? 1 : 0;
GetAACInfos(&b,&headertype,&fLength,&mi->file_info.bitrate,mi->src_size);
mi->file_info.bitrate*=1024;
mi->file_info.headertype=headertype;
mi->bytes_into_buffer=b.bytes_into_buffer;
mi->bytes_consumed=b.bytes_consumed;
IsSeekable=false; // only mp4 can be seeked
*/
if(!mi->FindBitrate) // open a new instance to get info from decoder
{
MYINPUT *miTmp;
Cfaad *NewInst;
if(!(NewInst=new Cfaad()))
return ERROR_getInfos("Memory allocation error: NewInst");
GLOBALLOCK(miTmp,NewInst->hInput,MYINPUT,return 0);
miTmp->FindBitrate=TRUE;
NewInst->ShowDlg4RawAAC=ShowDlg4RawAAC;
NewInst->pCfg=pCfg;
if(!NewInst->getInfos(lpstrFilename))
return ERROR_getInfos(0);
mi->Channels=miTmp->frameInfo.channels;
if(mi->file_info.headertype==RAW)
mi->file_info.bitrate=miTmp->file_info.bitrate;//*mi->Channels;
mi->Samprate=miTmp->Samprate;
mi->file_info.headertype=miTmp->file_info.headertype;
mi->file_info.object_type=miTmp->file_info.object_type;
mi->file_info.version=miTmp->file_info.version;
GlobalUnlock(NewInst->hInput);
delete NewInst;
}
if(!(mi->hDecoder=faacDecOpen()))
return ERROR_getInfos("Can't open library");
if(mi->file_info.headertype==RAW)
if(pCfg)
setFaadCfg(mi->hDecoder,*pCfg);
else
setDefaultFaadCfg(mi->hDecoder,mi->FindBitrate);
BYTE Channels; // faacDecInit doesn't report correctly the number of channels in raw aac files
if((mi->bytes_consumed=faacDecInit(mi->hDecoder, mi->buffer, mi->bytes_into_buffer, &mi->Samprate, &Channels))<0)
return ERROR_getInfos("faacDecInit()");
mi->bytes_into_buffer-=mi->bytes_consumed;
if(mi->FindBitrate) // get info from decoder
{
DWORD Samples,
BytesConsumed;
if(!processData(hInput,0,0))
return ERROR_getInfos(0);
Samples=mi->frameInfo.samples/sizeof(short);
BytesConsumed=mi->frameInfo.bytesconsumed;
if(mi->file_info.headertype==RAW || !mi->file_info.bitrate)
mi->file_info.bitrate=(BytesConsumed*8*mi->Samprate)/(Samples*2);
if(!mi->file_info.bitrate)
return ERROR_getInfos("Can't determine the bitrate");
}
mi->len_ms=(DWORD)((mi->src_size<<3)/(mi->file_info.bitrate>>10));
// mi->len_ms=(DWORD)((1000*((float)mi->src_size*8))/mi->file_info.bitrate);
}
if(mi->len_ms)
mi->dst_size=(DWORD)(mi->len_ms*((float)mi->Samprate/1000)*mi->Channels*(mi->BitsPerSample/8));
else
return ERROR_getInfos("Can't determine the length");
showInfo(mi);
GlobalUnlock(hInput);
return hInput;
}
// *********************************************************************************************
int Cfaad::processData(HANDLE hInput, unsigned char far *bufout, long lBytes)
{
BYTE *buffer;
DWORD BytesDecoded=0;
char *sample_buffer=0;
int read;
MYINPUT *mi;
GLOBALLOCK(mi,hInput,MYINPUT,return 0);
if(mi->LockSeeking)
{
NoSeek();
mi->LockSeeking=false;
}
if(mi->IsMP4) // MP4 file --------------------------------------------------------------------------
{
unsigned __int32 buffer_size=0;
int rc;
if(newpos_ms>-1)
{
MP4Duration duration=MP4ConvertToTrackDuration(mi->mp4File,mi->track,newpos_ms,MP4_MSECS_TIME_SCALE);
MP4SampleId sampleId=MP4GetSampleIdFromTime(mi->mp4File,mi->track,duration,0);
mi->bytes_read=(DWORD)(((float)newpos_ms*mi->file_info.bitrate)/(8*1000));
if(seek(mi->bytes_read)) // update the slider
return ERROR_processData(0);
newpos_ms=-1;
}
do
{
buffer=NULL;
if(mi->sampleId>=mi->numSamples)
return ERROR_processData(0);
rc=MP4ReadSample(mi->mp4File, mi->track, mi->sampleId++, (unsigned __int8 **)&buffer, &buffer_size, NULL, NULL, NULL, NULL);
if(rc==0 || buffer==NULL)
{
FREE_ARRAY(buffer);
return ERROR_processData("MP4ReadSample()");
}
sample_buffer=(char *)faacDecDecode(mi->hDecoder,&mi->frameInfo,buffer,buffer_size);
BytesDecoded=mi->frameInfo.samples*sizeof(short);
if(BytesDecoded>(DWORD)lBytes)
BytesDecoded=lBytes;
memmove(bufout,sample_buffer,BytesDecoded);
FREE_ARRAY(buffer);
// to update the slider
mi->bytes_read+=buffer_size;
if(seek(mi->bytes_read))
return ERROR_processData(0);
}while(!BytesDecoded && !mi->frameInfo.error);
}
else // AAC file --------------------------------------------------------------------------
{
if(newpos_ms>-1)
{
if(mi->IsSeekable)
{
DWORD normalized=mi->len_ms/(mi->seek_table_length-1);
if(normalized<1000)
normalized=1000;
mi->bytes_read=mi->seek_table[newpos_ms/normalized];
fseek(mi->aacFile, mi->bytes_read, SEEK_SET);
if(seek(mi->bytes_read)) // update the slider
return ERROR_processData(0);
mi->bytes_into_buffer=0;
mi->bytes_consumed=FAAD_STREAMSIZE;
}
newpos_ms=-1;
}
buffer=mi->buffer;
do
{
if(mi->bytes_consumed>0)
{
if(mi->bytes_into_buffer)
memmove(buffer,buffer+mi->bytes_consumed,mi->bytes_into_buffer);
if(mi->bytes_read<mi->src_size)
{
int tmp;
if(mi->bytes_read+mi->bytes_consumed<mi->src_size)
tmp=mi->bytes_consumed;
else
tmp=mi->src_size-mi->bytes_read;
read=fread(buffer+mi->bytes_into_buffer, 1, tmp, mi->aacFile);
if(read==tmp)
{
mi->bytes_read+=read;
mi->bytes_into_buffer+=read;
}
}
else
if(mi->bytes_into_buffer)
memset(buffer+mi->bytes_into_buffer, 0, mi->bytes_consumed);
mi->bytes_consumed=0;
if( (mi->bytes_into_buffer>3 && !memcmp(mi->buffer, "TAG", 3)) ||
(mi->bytes_into_buffer>11 && !memcmp(mi->buffer, "LYRICSBEGIN", 11)) ||
(mi->bytes_into_buffer>8 && !memcmp(mi->buffer, "APETAGEX", 8)))
return ERROR_processData(0);
}
if(mi->bytes_into_buffer<1)
if(mi->bytes_read<mi->src_size)
return ERROR_processData("Buffer empty!");
else
return ERROR_processData(0);
sample_buffer=(char *)faacDecDecode(mi->hDecoder,&mi->frameInfo,buffer,mi->bytes_into_buffer);
BytesDecoded=mi->frameInfo.samples*sizeof(short);
if(bufout)
{
if(BytesDecoded>(DWORD)lBytes)
BytesDecoded=lBytes;
if(sample_buffer && BytesDecoded && !mi->frameInfo.error)
memmove(bufout,sample_buffer,BytesDecoded);
}
else // Data needed to decode Raw files
{
mi->Channels=mi->frameInfo.channels;
mi->file_info.object_type=mi->frameInfo.object_type;
}
mi->bytes_consumed+=mi->frameInfo.bytesconsumed;
mi->bytes_into_buffer-=mi->bytes_consumed;
}while(!BytesDecoded && !mi->frameInfo.error);
} // END AAC file --------------------------------------------------------------------------
if(mi->frameInfo.error)
return ERROR_processData((char *)faacDecGetErrorMessage(mi->frameInfo.error));
showProgress(mi);
GlobalUnlock(hInput);
return BytesDecoded;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?