📄 coreaac.cpp
字号:
/* * CoreAAC - AAC DirectShow Decoder Filter * * Modification to decode AAC without ADTS and multichannel support * (c) 2003 christophe.paris@free.fr * * Under section 8 of the GNU General Public License, the copyright * holders of CoreAAC explicitly forbid distribution in the following * countries: * - Japan * - United States of America * * * AAC DirectShow Decoder Filter * Copyright (C) 2003 Robert Cioch * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ #include <windows.h>#include <streams.h>#include <initguid.h>#include <olectl.h>#include <transfrm.h>#include <mmreg.h>#include <ks.h>#include <ksmedia.h>#include <stdio.h>#include "AACProfilesName.h"#include "ICoreAAC.h"#include "CoreAACGUID.h"#include "CoreAACInfoProp.h"#include "CoreAACAboutProp.h"#include "CoreAAC.h"// ============================================================================// Registration setup stuffAMOVIESETUP_MEDIATYPE sudInputType[] ={ { &MEDIATYPE_Audio, &MEDIASUBTYPE_AAC }};AMOVIESETUP_MEDIATYPE sudOutputType[] ={ { &MEDIATYPE_Audio, &MEDIASUBTYPE_PCM }};AMOVIESETUP_PIN sudPins[] ={ { L"Input", FALSE, // bRendered FALSE, // bOutput FALSE, // bZero FALSE, // bMany &CLSID_NULL, // clsConnectsToFilter NULL, // ConnectsToPin NUMELMS(sudInputType), // Number of media types sudInputType }, { L"Output", FALSE, // bRendered TRUE, // bOutput FALSE, // bZero FALSE, // bMany &CLSID_NULL, // clsConnectsToFilter NULL, // ConnectsToPin NUMELMS(sudOutputType), // Number of media types sudOutputType }};AMOVIESETUP_FILTER sudDecoder ={ &CLSID_DECODER, L"CoreAAC Audio Decoder", MERIT_PREFERRED, NUMELMS(sudPins), sudPins};// ============================================================================// COM Global table of objects in this dllCFactoryTemplate g_Templates[] = { { L"CoreAAC Audio Decoder", &CLSID_DECODER, CCoreAACDecoder::CreateInstance, NULL, &sudDecoder }, { L"CoreAAC Audio Decoder Info", &CLSID_CoreAACInfoProp, CCoreAACInfoProp::CreateInstance, NULL, NULL}, { L"CoreAAC Audio Decoder About", &CLSID_CoreAACAboutProp, CCoreAACAboutProp::CreateInstance, NULL, NULL},};// Count of objects listed in g_cTemplatesint g_cTemplates = sizeof(g_Templates) / sizeof(g_Templates[0]);// ============================================================================STDAPI DllRegisterServer(){ return AMovieDllRegisterServer2(TRUE);}// ----------------------------------------------------------------------------STDAPI DllUnregisterServer(){ return AMovieDllRegisterServer2(FALSE);}// ----------------------------------------------------------------------------// The streams.h DLL entrypoint.extern "C" BOOL WINAPI DllEntryPoint(HINSTANCE, ULONG, LPVOID);// The entrypoint required by the MSVC runtimes. This is used instead// of DllEntryPoint directly to ensure global C++ classes get initialised.BOOL WINAPI DllMain(HANDLE hDllHandle, DWORD dwReason, LPVOID lpreserved) { return DllEntryPoint(reinterpret_cast<HINSTANCE>(hDllHandle), dwReason, lpreserved);}// ----------------------------------------------------------------------------CUnknown *WINAPI CCoreAACDecoder::CreateInstance(LPUNKNOWN punk, HRESULT *phr){ CCoreAACDecoder *pNewObject = new CCoreAACDecoder(punk, phr); if (!pNewObject) *phr = E_OUTOFMEMORY; return pNewObject;}// ----------------------------------------------------------------------------void SaveInt(char* keyname, int value){ HKEY hKey; DWORD dwDisp; if (ERROR_SUCCESS == RegCreateKeyEx(HKEY_CURRENT_USER, "Software\\CoreAAC", 0, "REG_SZ", REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, &dwDisp)) { DWORD dwSize = sizeof(DWORD); RegSetValueEx(hKey, keyname, 0, REG_DWORD, (CONST BYTE*)&value, dwSize); RegCloseKey(hKey); }}int LoadInt(char* keyname, int default_value){ HKEY hKey; int result = default_value; if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\CoreAAC", 0, KEY_READ, &hKey)) { DWORD dwTmp = 0; DWORD dwcbData = sizeof(DWORD); if(RegQueryValueEx(hKey, keyname, NULL, NULL, (LPBYTE) &dwTmp, &dwcbData) == ERROR_SUCCESS) { result = dwTmp; } RegCloseKey(hKey); } return result;}// ----------------------------------------------------------------------------CCoreAACDecoder::CCoreAACDecoder(LPUNKNOWN lpunk, HRESULT *phr) : CTransformFilter(NAME("CoreAAC Audio Decoder"), lpunk, CLSID_DECODER), m_decHandle(NULL), m_decoderSpecificLen(0), m_decoderSpecific(NULL), m_Channels(0), m_SamplesPerSec(0), m_BitsPerSample(0), m_Bitrate(0), m_brCalcFrames(0), m_brBytesConsumed(0), m_DecodedFrames(0), m_OutputBuffLen(0), m_DownMatrix(false){ NOTE("CCoreAACDecoder::CCoreAACDecoder"); m_ProfileName[0] = '\0'; m_DownMatrix = LoadInt("DownMatrix", TRUE) ? true : false; }// ----------------------------------------------------------------------------CCoreAACDecoder::~CCoreAACDecoder(){ NOTE("CCoreAACDecoder::~CCoreAACDecoder"); SaveInt("DownMatrix",m_DownMatrix); if(m_decHandle) { faacDecClose(m_decHandle); m_decHandle = NULL; } if(m_decoderSpecific) { delete m_decoderSpecific; m_decoderSpecific = NULL; }}// ----------------------------------------------------------------------------STDMETHODIMP CCoreAACDecoder::NonDelegatingQueryInterface(REFIID riid, void **ppv){ if(riid == IID_ICoreAACDec) return GetInterface((ICoreAACDec *)this, ppv); else if (riid == IID_ISpecifyPropertyPages) return GetInterface((ISpecifyPropertyPages *)this, ppv); else return CTransformFilter::NonDelegatingQueryInterface(riid, ppv);}// ----------------------------------------------------------------------------// property pagesSTDMETHODIMP CCoreAACDecoder::GetPages(CAUUID *pPages){ pPages->cElems = 2; pPages->pElems = (GUID *)CoTaskMemAlloc(pPages->cElems * sizeof(GUID)); if (!pPages->pElems) return E_OUTOFMEMORY; pPages->pElems[0] = CLSID_CoreAACInfoProp; pPages->pElems[1] = CLSID_CoreAACAboutProp; return S_OK;} // ============================================================================// accept only aac audio wrapped in waveformatHRESULT CCoreAACDecoder::CheckInputType(const CMediaType *mtIn){ if (*mtIn->Type() != MEDIATYPE_Audio || *mtIn->Subtype() != MEDIASUBTYPE_AAC) return VFW_E_TYPE_NOT_ACCEPTED; if (*mtIn->FormatType() != FORMAT_WaveFormatEx) return VFW_E_TYPE_NOT_ACCEPTED; WAVEFORMATEX *wfex = (WAVEFORMATEX *)mtIn->Format(); if (wfex->wFormatTag != WAVE_FORMAT_AAC) return VFW_E_TYPE_NOT_ACCEPTED; if(wfex->cbSize < 2) return VFW_E_TYPE_NOT_ACCEPTED; m_decoderSpecificLen = wfex->cbSize; if(m_decoderSpecific) { delete m_decoderSpecific; m_decoderSpecific = NULL; } m_decoderSpecific = new unsigned char[m_decoderSpecificLen]; // Keep decoderSpecific initialization data (appended to the WAVEFORMATEX struct) memcpy(m_decoderSpecific,(char*)wfex+sizeof(WAVEFORMATEX), m_decoderSpecificLen); return S_OK;}// ============================================================================// propose proper waveformatHRESULT CCoreAACDecoder::GetMediaType(int iPosition, CMediaType *mtOut){ if (!m_pInput->IsConnected()) { return E_UNEXPECTED; } if (iPosition < 0) { return E_INVALIDARG; } if (iPosition > 0) { return VFW_S_NO_MORE_ITEMS; } // Some drivers don't like WAVEFORMATEXTENSIBLE when channels are <= 2 so // we fall back to a classic WAVEFORMATEX struct in this case WAVEFORMATEXTENSIBLE wfex; ZeroMemory(&wfex, sizeof(WAVEFORMATEXTENSIBLE)); wfex.SubFormat = KSDATAFORMAT_SUBTYPE_PCM; wfex.Format.wFormatTag = (m_Channels <= 2) ? WAVE_FORMAT_PCM : WAVE_FORMAT_EXTENSIBLE; wfex.Format.cbSize = (m_Channels <= 2) ? 0 : sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX); wfex.Format.nChannels = (unsigned short)m_Channels; wfex.Format.nSamplesPerSec = (unsigned short)m_SamplesPerSec; wfex.Format.wBitsPerSample = m_BitsPerSample; wfex.Format.nBlockAlign = (unsigned short)((wfex.Format.nChannels * wfex.Format.wBitsPerSample) / 8); wfex.Format.nAvgBytesPerSec = wfex.Format.nSamplesPerSec * wfex.Format.nBlockAlign; switch(m_Channels)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -