📄 coreaac.cpp
字号:
{
case 1:
wfex.dwChannelMask = KSAUDIO_SPEAKER_MONO;
break;
case 2:
wfex.dwChannelMask = KSAUDIO_SPEAKER_STEREO;
break;
case 3:
wfex.dwChannelMask = KSAUDIO_SPEAKER_STEREO | SPEAKER_FRONT_CENTER;
break;
case 4:
//wfex.dwChannelMask = KSAUDIO_SPEAKER_QUAD;
wfex.dwChannelMask = (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_BACK_CENTER);
break;
case 5:
wfex.dwChannelMask = KSAUDIO_SPEAKER_QUAD | SPEAKER_FRONT_CENTER;
break;
case 6:
wfex.dwChannelMask = KSAUDIO_SPEAKER_5POINT1;
break;
default:
wfex.dwChannelMask = KSAUDIO_SPEAKER_DIRECTOUT; // XXX : or SPEAKER_ALL ??
break;
}
wfex.Samples.wValidBitsPerSample = wfex.Format.wBitsPerSample;
mtOut->SetType(&MEDIATYPE_Audio);
mtOut->SetSubtype(&MEDIASUBTYPE_PCM);
mtOut->SetFormatType(&FORMAT_WaveFormatEx);
mtOut->SetFormat( (BYTE*) &wfex, sizeof(WAVEFORMATEX)+wfex.Format.cbSize);
mtOut->SetTemporalCompression(FALSE);
return S_OK;
}
// ----------------------------------------------------------------------------
HRESULT CCoreAACDecoder::CheckTransform(const CMediaType *mtIn, const CMediaType *mtOut)
{
if (*mtOut->Type() != MEDIATYPE_Audio ||
*mtOut->Subtype() != MEDIASUBTYPE_PCM ||
*mtOut->FormatType() != FORMAT_WaveFormatEx)
{
return VFW_E_TYPE_NOT_ACCEPTED;
}
return S_OK;
}
// ----------------------------------------------------------------------------
// 960 for LD or else 1024 (expanded to 2048 for HE-AAC)
#define MAXFRAMELEN 2048
HRESULT CCoreAACDecoder::DecideBufferSize(IMemAllocator *pAllocator, ALLOCATOR_PROPERTIES *pProperties)
{
pProperties->cBuffers = 8;
m_OutputBuffLen = m_Channels * MAXFRAMELEN * sizeof(short);
pProperties->cbBuffer = m_OutputBuffLen;
NOTE1("CCoreAACDecoder::DecideBufferSize %d", pProperties->cbBuffer);
ALLOCATOR_PROPERTIES Actual;
HRESULT hr = pAllocator->SetProperties(pProperties, &Actual);
if(FAILED(hr))
return hr;
if (Actual.cbBuffer < pProperties->cbBuffer || Actual.cBuffers < pProperties->cBuffers)
return E_INVALIDARG;
return S_OK;
}
// ----------------------------------------------------------------------------
HRESULT CCoreAACDecoder::CompleteConnect(PIN_DIRECTION direction, IPin *pReceivePin)
{
HRESULT hr = CTransformFilter::CompleteConnect(direction, pReceivePin);
if(direction == PINDIR_INPUT)
{
if(m_decHandle)
{
faacDecClose(m_decHandle);
m_decHandle = NULL;
}
m_decHandle = faacDecOpen();
faacDecConfigurationPtr config;
config = faacDecGetCurrentConfiguration(m_decHandle);
config->downMatrix = m_DownMatrix;
faacDecSetConfiguration(m_decHandle, config);
// Initialize the decoder
unsigned long SamplesPerSec = 0;
unsigned char Channels = 0;
if(faacDecInit2(m_decHandle, m_decoderSpecific, m_decoderSpecificLen,
&SamplesPerSec, &Channels) < 0)
{
return E_FAIL;
}
if(m_DownMatrix)
{
Channels = 2; // TODO : check with mono
}
mp4AudioSpecificConfig info;
AudioSpecificConfig(m_decoderSpecific,m_decoderSpecificLen,&info);
wsprintf(m_ProfileName,"%s%s",
ObjectTypesNameTable[info.objectTypeIndex],
#if 0
info.sbr_present_flag ?
#else
false ?
#endif
"+SBR" :
""
);
m_Channels = Channels;
m_SamplesPerSec = SamplesPerSec;
m_BitsPerSample = 16; // we always decode to the default 16 bits (we could add 24,32,float)
m_brCalcFrames = 0;
m_brBytesConsumed = 0;
m_DecodedFrames = 0;
}
return hr;
}
// ----------------------------------------------------------------------------
HRESULT CCoreAACDecoder::StartStreaming(void)
{
m_brCalcFrames = 0;
m_brBytesConsumed = 0;
m_DecodedFrames = 0;
return CTransformFilter::StartStreaming();
}
// ----------------------------------------------------------------------------
HRESULT CCoreAACDecoder::Transform(IMediaSample *pIn, IMediaSample *pOut)
{
if (m_State == State_Stopped)
{
pOut->SetActualDataLength(0);
return S_OK;
}
if(pIn->IsPreroll() == S_OK)
{
return S_FALSE;
}
// Decode the sample data
DWORD ActualDstLength;
BYTE *pSrc, *pDst;
DWORD SrcLength = pIn->GetActualDataLength();
DWORD DstLength = pOut->GetSize();
HRESULT hr;
hr = pIn->GetPointer(&pSrc);
if(hr != S_OK)
return hr;
hr = pOut->GetPointer(&pDst);
if(hr != S_OK)
return hr;
if(!pSrc || !pDst || (DstLength < m_OutputBuffLen))
return S_FALSE;
// Decode data
// (use our buffer calculated len, as the Waveout renderer seems to report wrongly a bigger size)
if(!Decode(pSrc, SrcLength, pDst, m_OutputBuffLen, &ActualDstLength))
return S_FALSE;
NOTE3("Transform: %u->%u (%u)\n", SrcLength, ActualDstLength, m_OutputBuffLen);
// Copy the actual data length
pOut->SetActualDataLength(ActualDstLength);
return S_OK;
}
// ----------------------------------------------------------------------------
// AAC order : C, L, R, L", R", LFE
// DShow order : L, R, C, LFE, L", R"
const int MAXCHANNELS = 6;
const int chmap[MAXCHANNELS][MAXCHANNELS+1] = {
// first column tell us if we need to remap
{ 0, }, // mono
{ 0, }, // l, r
{ 1, 1, 2, 0, }, // c ,l, r -> l, r, c
{ 1, 1, 2, 0, 3, }, // c, l, r, bc -> l, r, c, bc
{ 1, 1, 2, 0, 3, 4, }, // c, l, r, bl, br -> l, r, c, bl, br
{ 1, 1, 2, 0, 5, 3, 4 } // c, l, r, bl, br, lfe -> l, r, c, lfe, bl, br
};
// ----------------------------------------------------------------------------
bool CCoreAACDecoder::Decode(BYTE *pSrc, DWORD SrcLength, BYTE *pDst, DWORD DstLength, DWORD *ActualDstLength)
{
faacDecFrameInfo frameInfo;
short *outsamples = (short *)faacDecDecode(m_decHandle, &frameInfo, pSrc, DstLength);
if (frameInfo.error)
{
NOTE2("CCoreAACDecoder::Decode Error %d [%s]\n",
frameInfo.error, faacDecGetErrorMessage(frameInfo.error));
return false;
}
m_brCalcFrames++;
m_DecodedFrames++;
m_brBytesConsumed += SrcLength;
if(m_brCalcFrames == 43)
{
m_Bitrate = (int)((m_brBytesConsumed * 8) / (m_DecodedFrames / 43.07));
m_brCalcFrames = 0;
}
if (!frameInfo.error && outsamples)
{
int channelidx = frameInfo.channels-1;
if(chmap[channelidx][0])
{
// dshow remapping
short *dstBuffer = (short*)pDst;
for(unsigned int i = 0;
i < frameInfo.samples;
i += frameInfo.channels, outsamples += frameInfo.channels)
{
for(unsigned int j=1; j <= frameInfo.channels; j++)
{
*dstBuffer++ = outsamples[chmap[channelidx][j]];
}
}
}
else
{
memcpy(pDst, outsamples, frameInfo.samples * sizeof(short));
}
}
else
return false;
*ActualDstLength = frameInfo.samples * sizeof(short);
return true;
}
// ============================================================================
// ICoreAAC
// ============================================================================
STDMETHODIMP CCoreAACDecoder::get_ProfileName(char** name)
{
CheckPointer(name,E_POINTER);
*name = m_ProfileName;
return S_OK;
}
STDMETHODIMP CCoreAACDecoder::get_SampleRate(int* sample_rate)
{
CheckPointer(sample_rate,E_POINTER);
*sample_rate = m_SamplesPerSec;
return S_OK;
}
STDMETHODIMP CCoreAACDecoder::get_Channels(int *channels)
{
CheckPointer(channels,E_POINTER);
*channels = m_Channels;
return S_OK;
}
STDMETHODIMP CCoreAACDecoder::get_BitsPerSample(int *bits_per_sample)
{
CheckPointer(bits_per_sample,E_POINTER);
*bits_per_sample = m_BitsPerSample;
return S_OK;
}
STDMETHODIMP CCoreAACDecoder::get_Bitrate(int *bitrate)
{
CheckPointer(bitrate,E_POINTER);
*bitrate = m_Bitrate;
return S_OK;
}
STDMETHODIMP CCoreAACDecoder::get_FramesDecoded(unsigned int *frames_decoded)
{
CheckPointer(frames_decoded,E_POINTER);
*frames_decoded = m_DecodedFrames;
return S_OK;
}
STDMETHODIMP CCoreAACDecoder::get_DownMatrix(bool *down_matrix)
{
CheckPointer(down_matrix,E_POINTER);
*down_matrix = m_DownMatrix;
return S_OK;
}
STDMETHODIMP CCoreAACDecoder::set_DownMatrix(bool down_matrix)
{
m_DownMatrix = down_matrix;
return S_OK;
}
// ============================================================================
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -