📄 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 2048HRESULT 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 + -