📄 codec.cpp
字号:
stream* pstr=(stream*)pStream->dwDriver;
return pstr->size(pSize);
}
HRESULT codec::unprepare(ACMDRVSTREAMINSTANCE* pStream, ACMDRVSTREAMHEADER* pHeader)
{
return MMSYSERR_NOTSUPPORTED;
}
HRESULT codec::convert(ACMDRVSTREAMINSTANCE* pStream, ACMDRVSTREAMHEADER* pHeader)
{
stream* pstr=(stream*)pStream->dwDriver;
return pstr->convert(pHeader);
}
HRESULT codec::close(ACMDRVSTREAMINSTANCE* pStream)
{
stream* pstr=(stream*)pStream->dwDriver;
delete pstr;
return MMSYSERR_NOERROR;
}
#include "faac.h"
codec::encoder::encoder(WAVEFORMATEX* pF, WAVEFORMATEX* pFDest) : m_sFormat(*pF)
{
m_iOutputBytesPerSec=pFDest->nAvgBytesPerSec;
m_pHandle=faacEncOpen(pF->nSamplesPerSec, pF->nChannels, &m_iInputSamples, &m_iMaxOutputBytes);
faacEncConfiguration conf;
conf.mpegVersion = MPEG4;
conf.aacObjectType = MAIN;
conf.allowMidside = 1;
conf.useLfe = 1;
conf.useTns = 1;
conf.bitRate = m_iOutputBytesPerSec/pFDest->nChannels; // bits/second per channel
conf.bandWidth = 18000; //Hz
conf.outputFormat = 1; // ADTS
faacEncSetConfiguration(m_pHandle, &conf);
}
HRESULT codec::encoder::reset()
{
// fixme (?)
return MMSYSERR_NOERROR;
}
HRESULT codec::encoder::size(ACMDRVSTREAMSIZE* pSize)
{
double dwInputBitRate=m_sFormat.nSamplesPerSec * m_sFormat.wBitsPerSample * m_sFormat.nChannels;
double dwOutputBitRate=m_iOutputBytesPerSec;// kbytes/s
if(pSize->fdwSize == ACM_STREAMSIZEF_SOURCE)
{
if(pSize->cbSrcLength<2*m_iInputSamples)
pSize->cbSrcLength=2*m_iInputSamples;
pSize->cbDstLength = pSize->cbSrcLength * 2 * dwOutputBitRate/dwInputBitRate;
if(pSize->cbDstLength<m_iMaxOutputBytes)
pSize->cbDstLength=m_iMaxOutputBytes;
}
else
{
if(pSize->cbDstLength<m_iMaxOutputBytes)
pSize->cbDstLength=m_iMaxOutputBytes;
pSize->cbSrcLength = pSize->cbDstLength * 2 * dwInputBitRate/dwOutputBitRate;;
if(pSize->cbSrcLength<2*m_iInputSamples)
pSize->cbSrcLength=2*m_iInputSamples;
}
return MMSYSERR_NOERROR;
}
#include <stdio.h>
HRESULT codec::encoder::convert(ACMDRVSTREAMHEADER* pHeader)
{
#if 0
short* pSrc, *pDst;
pSrc=(short*)(pHeader->pbSrc);
pDst=(short*)(pHeader->pbDst);
int iSrc=0, iDst=0;
int block_size=m_sFormat.nChannels * 64;
int samples_to_process=pHeader->cbSrcLength / (2 * block_size);
for(int j=0; j<samples_to_process; j++)
{
if(m_sFormat.nChannels==1)
{
pDst[0]=pSrc[0];
for(int i=1; i<64; i++)
pDst[i]=(int)pSrc[i]-(int)pSrc[i-1];
pSrc+=block_size;
pDst+=block_size;
}
else
{
pDst[0]=pSrc[0];
pDst[1]=pSrc[1];
for(int i=1; i<64; i++)
{
pDst[2*i]=(int)pSrc[2*i]-(int)pSrc[2*i-2];
pDst[2*i+1]=(int)pSrc[2*i+1]-(int)pSrc[2*i-1];
}
pSrc+=block_size;
pDst+=block_size;
}
}
FILE* f=fopen("c:\\enc.log", "ab");
fwrite(pHeader->pbSrc, 2 * block_size * samples_to_process, 1, f);
fclose(f);
f=fopen("c:\\enc2.log", "ab");
fwrite(pHeader->pbDst, 2 * block_size * samples_to_process, 1, f);
fclose(f);
pHeader->cbDstLengthUsed=2 * block_size * samples_to_process;
pHeader->cbSrcLengthUsed=2 * block_size * samples_to_process;
return MMSYSERR_NOERROR;
#else
short* buffer=0;
int length=pHeader->cbSrcLength;
if(m_sFormat.wBitsPerSample!=16)
{
buffer = new short[length];
for(int i=0; i<length; i++)
{
short s=(short)(((unsigned char*)pHeader->pbSrc)[i]);
s-=128;
s*=256;
buffer[i]=s;
}
}
short* pointer = buffer ? buffer : (short*)(pHeader->pbSrc);
pHeader->cbSrcLengthUsed=0;
pHeader->cbDstLengthUsed=0;
while(1)
{
if(length-pHeader->cbSrcLengthUsed<2*m_iInputSamples)
break;
if(pHeader->cbDstLength-pHeader->cbDstLengthUsed<m_iMaxOutputBytes)
break;
int result=faacEncEncode(m_pHandle, pointer+pHeader->cbSrcLengthUsed,
m_iInputSamples,
(short*)(pHeader->pbDst+pHeader->cbDstLengthUsed),
pHeader->cbDstLength-pHeader->cbDstLengthUsed);
if(result<0)
{
reset();
break;
}
pHeader->cbDstLengthUsed+=result;
pHeader->cbSrcLengthUsed+=2*m_iInputSamples;
}
if(buffer)
{
pHeader->cbSrcLengthUsed/=2;
delete[] buffer;
}
return MMSYSERR_NOERROR;
#endif
}
codec::decoder::decoder(WAVEFORMATEX* pF) : m_sFormat(*pF), m_bInitialized(false), m_pCache(0)
{
m_pHandle=faacDecOpen();
}
HRESULT codec::decoder::reset()
{
faacDecClose(m_pHandle);
m_pHandle=faacDecOpen();
m_bInitialized=false;
delete[] m_pCache;
m_pCache=0;
return MMSYSERR_NOERROR;
}
HRESULT codec::decoder::size(ACMDRVSTREAMSIZE* pSize)
{
double dwInputBitRate=m_sFormat.nAvgBytesPerSec;
double dwOutputBitRate=m_sFormat.nSamplesPerSec * m_sFormat.wBitsPerSample * m_sFormat.nChannels;
if(pSize->fdwSize == ACM_STREAMSIZEF_SOURCE)
{
if(pSize->cbSrcLength<768*m_sFormat.nChannels)
pSize->cbSrcLength=768*m_sFormat.nChannels;
pSize->cbDstLength = pSize->cbSrcLength * 2 * dwOutputBitRate/dwInputBitRate;
if(pSize->cbDstLength<4096)
pSize->cbDstLength=4096;
}
else
{
if(pSize->cbDstLength<4096)
pSize->cbDstLength=4096;
pSize->cbSrcLength = pSize->cbDstLength * 2 * dwInputBitRate/dwOutputBitRate;;
if(pSize->cbSrcLength<768*m_sFormat.nChannels)
pSize->cbSrcLength=768*m_sFormat.nChannels;
}
return MMSYSERR_NOERROR;
}
//static int iBytesProcessed=0;
HRESULT codec::decoder::convert(ACMDRVSTREAMHEADER* pHeader)
{
#if 0
short *pSrc, *pDst;
pSrc=(short*)pHeader->pbSrc;
pDst=(short*)pHeader->pbDst;
int iSrc=0, iDst=0;
int block_size=m_sFormat.nChannels * 64;
int samples_to_process=pHeader->cbSrcLength / (2 * block_size);
for(int j=0; j<samples_to_process; j++)
{
if(m_sFormat.nChannels==1)
{
pDst[0]=pSrc[0];
for(int i=1; i<64; i++)
pDst[i]=(int)pSrc[i]+(int)pDst[i-1];
pSrc+=block_size;
pDst+=block_size;
}
else
{
pDst[0]=pSrc[0];
pDst[1]=pSrc[1];
for(int i=1; i<64; i++)
{
pDst[2*i]=(int)pSrc[2*i]+(int)pDst[2*i-2];
pDst[2*i+1]=(int)pSrc[2*i+1]+(int)pDst[2*i-1];
}
pSrc+=block_size;
pDst+=block_size;
}
}
FILE* f=fopen("c:\\dec.log", "ab");
fwrite(pHeader->pbDst, 2 * block_size * samples_to_process, 1, f);
fclose(f);
pHeader->cbDstLengthUsed=2 * block_size * samples_to_process;
pHeader->cbSrcLengthUsed=2 * block_size * samples_to_process;
return MMSYSERR_NOERROR;
#else
// fixme: check fdwConvert contents
const int iMinInputSize = 768*m_sFormat.nChannels;
pHeader->cbSrcLengthUsed=0;
pHeader->cbDstLengthUsed=0;
int decoded_bytes=0;
if(!m_bInitialized)
{
unsigned long samplerate;
unsigned long channels;
//assert(!m_pCache);
// we don't really need this call
// and it is done only because i am not sure if it's necessary for faac functionality
pHeader->cbSrcLengthUsed=faacDecInit(m_pHandle, pHeader->pbSrc, &samplerate, &channels);
m_bInitialized=true;
}
unsigned long bytesconsumed;
unsigned long samples;
if(pHeader->cbDstLength<4096)
goto finish;
int iSrcDataLeft=pHeader->cbSrcLength;
while(m_pCache)
{
int iFillSize = iMinInputSize - m_iCacheSize;
if(iFillSize > iSrcDataLeft)
iFillSize = iSrcDataLeft;
memcpy(&m_pCache[m_iCacheSize], pHeader->pbSrc+pHeader->cbSrcLengthUsed, iFillSize);
m_iCacheSize += iFillSize;
iSrcDataLeft -= iFillSize;
pHeader->cbSrcLengthUsed += iFillSize;
if(m_iCacheSize < iMinInputSize)
goto finish;
int result=faacDecDecode(m_pHandle, m_pCache, &bytesconsumed,
(short*)(pHeader->pbDst+pHeader->cbDstLengthUsed), &samples); // no way to prevent output buffer overrun???
if(result==FAAD_FATAL_ERROR)
{
reset();
goto finish;
}
if(result==FAAD_OK)
pHeader->cbDstLengthUsed+=sizeof(short)*samples;
assert(bytesconsumed <= iMinInputSize);
if(bytesconsumed < iMinInputSize)
memmove(m_pCache, &m_pCache[bytesconsumed], iMinInputSize-bytesconsumed);
m_iCacheSize-=bytesconsumed;
if(m_iCacheSize==0)
{
delete[] m_pCache;
m_pCache=0;
}
}
if(iSrcDataLeft == 0)
goto finish;
if(iSrcDataLeft < iMinInputSize)
{
m_pCache = new unsigned char[iMinInputSize];
memcpy(m_pCache, pHeader->pbSrc + pHeader->cbSrcLengthUsed, iSrcDataLeft);
m_iCacheSize = iSrcDataLeft;
pHeader->cbSrcLengthUsed = pHeader->cbSrcLength;
goto finish;
}
while(iSrcDataLeft>=iMinInputSize)
{
if(pHeader->cbDstLength-pHeader->cbDstLengthUsed<4096)
break;
int result=faacDecDecode(m_pHandle, pHeader->pbSrc+pHeader->cbSrcLengthUsed, &bytesconsumed,
(short*)(pHeader->pbDst+pHeader->cbDstLengthUsed), &samples); // no way to prevent output buffer overrun???
if(result==FAAD_FATAL_ERROR)
{
pHeader->cbSrcLengthUsed=pHeader->cbSrcLength;
reset();
goto finish;
}
if(result==FAAD_OK)
pHeader->cbDstLengthUsed+=sizeof(short)*samples;
pHeader->cbSrcLengthUsed+=bytesconsumed;
iSrcDataLeft-=bytesconsumed;
}
finish:
FILE* f=fopen("c:\\aac_acm.bin", "ab");
fwrite(pHeader->pbSrc, pHeader->cbSrcLengthUsed, 1, f);
fclose(f);
// iBytesProcessed+=pHeader->cbSrcLengthUsed;
return MMSYSERR_NOERROR;
#endif
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -