⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 coreaac.cpp

📁 AAC编解码源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/* 
 * 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 stuff

AMOVIESETUP_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 dll

CFactoryTemplate 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_cTemplates
int 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 pages

STDMETHODIMP 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 waveformat

HRESULT 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 waveformat

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