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

📄 coreaac.cpp

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