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

📄 cmpeg1builder.cpp

📁 非常有用的VC视频音频开发所需要的东西 需要有用
💻 CPP
字号:
//
// CMPEG1Builder.cpp
//

#include <streams.h>
#include "FltGuids.h"
#include "CMPEG1Builder.h"

/////////////////////////////////////////////////////////////////////////////
CMPEG1Builder::CMPEG1Builder(LPUNKNOWN pUnk, HRESULT *phr) :
CUnknown(NAME("MPEG1 Builder"), pUnk)
{
}

CMPEG1Builder::~CMPEG1Builder()
{
}

//
// Expose our own interface
STDMETHODIMP CMPEG1Builder::NonDelegatingQueryInterface(REFIID riid, void ** ppv)
{
	CheckPointer(ppv, E_POINTER);

	if (riid == IID_IMPEG1Builder) 
	{
		return GetInterface((IMPEG1Builder *) this, ppv);
	}
	else if (riid == IID_IDistributorNotify)
	{
		return GetInterface((IDistributorNotify *) this, ppv);
	}
	else
	{
		return CUnknown::NonDelegatingQueryInterface(riid, ppv);
	}
}

// --- IMPEG1Builder methods ---
STDMETHODIMP CMPEG1Builder::IsMPEG1File(const char * inFilePath)
{
	IGraphBuilder * pBuilder = RetrieveGraphBuilder();

	// Create a file source filter
	IBaseFilter * pSource = NULL;
	WCHAR  wcFilePath[MAX_PATH];
	MultiByteToWideChar(CP_ACP, 0, inFilePath, -1, wcFilePath, MAX_PATH);
	pBuilder->AddSourceFilter(wcFilePath, L"Source", &pSource);
	pSource->Release();

	// Create microsoft MPEG-1 Stream Splitter
	IBaseFilter * pSplitter = NULL;
	CoCreateInstance(CLSID_MPEG1Splitter , NULL, CLSCTX_INPROC_SERVER,
		IID_IBaseFilter, (void **)&pSplitter);
	pBuilder->AddFilter(pSplitter, L"MPEG-1 Splitter");
	pSplitter->Release();

	// Try to connect them...
	IPin * pOut = GetPinByDirection(pSource, PINDIR_OUTPUT);
	IPin * pIn  = GetPinByDirection(pSplitter, PINDIR_INPUT);
	HRESULT hr  = pBuilder->ConnectDirect(pOut, pIn, NULL);
	
	pBuilder->RemoveFilter(pSplitter);
	pBuilder->RemoveFilter(pSource);

	return SUCCEEDED(hr) ? S_OK : S_FALSE;
}

STDMETHODIMP CMPEG1Builder::RenderMPEG1File(const char * inFilePath)
{
	IGraphBuilder * pBuilder = RetrieveGraphBuilder();

	// Create a file source filter
	IBaseFilter * pSource = NULL;
	WCHAR  wcFilePath[MAX_PATH];
	MultiByteToWideChar(CP_ACP, 0, inFilePath, -1, wcFilePath, MAX_PATH);
	pBuilder->AddSourceFilter(wcFilePath, L"Source", &pSource);
	pSource->Release();

	// Create microsoft MPEG-1 Stream Splitter
	IBaseFilter * pSplitter = NULL;
	CoCreateInstance(CLSID_MPEG1Splitter , NULL, CLSCTX_INPROC_SERVER,
		IID_IBaseFilter, (void **)&pSplitter);
	pBuilder->AddFilter(pSplitter, L"MPEG-1 Splitter");
	pSplitter->Release();

	// Create microsoft MPEG-1 Video Decoder
	IBaseFilter * pVideoDec = NULL;
	CoCreateInstance(CLSID_CMpegVideoCodec, NULL, CLSCTX_INPROC_SERVER,
		IID_IBaseFilter, (void **)&pVideoDec);
	pBuilder->AddFilter(pVideoDec, L"MPEG-1 Video Decoder");
	pVideoDec->Release();

	// Create microsoft MPEG-1 Audio Dedocer
	IBaseFilter * pAudioDec = NULL;
	CoCreateInstance(CLSID_CMpegAudioCodec, NULL, CLSCTX_INPROC_SERVER,
		IID_IBaseFilter, (void **)&pAudioDec);
	pBuilder->AddFilter(pAudioDec, L"MPEG-1 Audio Decoder");
	pAudioDec->Release();

	// Connect filters...
	IPin * pOut = GetPinByDirection(pSource, PINDIR_OUTPUT);
	IPin * pIn  = GetPinByDirection(pSplitter, PINDIR_INPUT);
	HRESULT hr  = pBuilder->ConnectDirect(pOut, pIn, NULL);
	pOut = GetPinByName(pSplitter, "Video");
	pIn  = GetPinByDirection(pVideoDec, PINDIR_INPUT);
	if (pOut && pIn)
	{
		hr = pBuilder->ConnectDirect(pOut, pIn, NULL);
	}
	pOut = GetPinByName(pSplitter, "Audio");
	pIn  = GetPinByDirection(pAudioDec, PINDIR_INPUT);
	if (pOut && pIn)
	{
		hr = pBuilder->ConnectDirect(pOut, pIn, NULL);
	}

	// Auto-build the rest of the filter graph
	IPin * connected = NULL;
	pIn = GetPinByDirection(pVideoDec, PINDIR_INPUT);
	hr  = pIn->ConnectedTo(&connected);
	if (SUCCEEDED(hr) && connected)
	{
		connected->Release();
		hr = pBuilder->Render(GetPinByDirection(pVideoDec, PINDIR_OUTPUT));
	}
	else
	{
		pBuilder->RemoveFilter(pVideoDec);
	}

	pIn = GetPinByDirection(pAudioDec, PINDIR_INPUT);
	hr  = pIn->ConnectedTo(&connected);
	if (SUCCEEDED(hr) && connected)
	{
		connected->Release();
		hr = pBuilder->Render(GetPinByDirection(pAudioDec, PINDIR_OUTPUT));
	}
	else
	{
		pBuilder->RemoveFilter(pAudioDec);
	}

	return hr;
}

// Utilities
IGraphBuilder * CMPEG1Builder::RetrieveGraphBuilder(void)
{
	IGraphBuilder * pBuilder = NULL;
	QueryInterface(IID_IGraphBuilder, (void**)&pBuilder);
	pBuilder->Release();
	return pBuilder;
}

IPin * CMPEG1Builder::GetPinByDirection(IBaseFilter * inFilter, PIN_DIRECTION inDirection)
{
	IPin * foundPin = NULL;
	if (inFilter)
	{
		IEnumPins * pinEnum = 0;
		if (SUCCEEDED(inFilter->EnumPins(&pinEnum)))
		{
			pinEnum->Reset();

			IPin * pin = 0;
			ULONG fetchCount = 0;
			while (!foundPin && SUCCEEDED(pinEnum->Next(1, &pin, &fetchCount)) && fetchCount)
			{
				if (pin)
				{
					PIN_INFO pinInfo;
					if (SUCCEEDED(pin->QueryPinInfo(&pinInfo)))
					{
						pinInfo.pFilter->Release();
						if (pinInfo.dir == inDirection)
						{
							foundPin = pin;
						}
					}
					// If found pin, we keep pin reference.
					// If not, we release it here.
					if (!foundPin)
					{
						pin->Release();
					}
					pin = 0;
				}
			}
			pinEnum->Release();
		}
	}

	// We don't keep outstanding reference count
	if (foundPin)
	{
		foundPin->Release();
	}
	return foundPin;
}

IPin * CMPEG1Builder::GetPinByName(IBaseFilter * inFilter, const char * inPinName, BOOL inInput)
{
	PIN_DIRECTION pinType = inInput ? PINDIR_INPUT : PINDIR_OUTPUT;
	IPin * foundPin = 0;
	if (inFilter)
	{
		IEnumPins * pinEnum = 0;
		if (SUCCEEDED(inFilter->EnumPins(&pinEnum)))
		{
			pinEnum->Reset();
			IPin * pin = 0;
			ULONG fetchCount = 0;
			while (!foundPin && SUCCEEDED(pinEnum->Next(1, &pin, &fetchCount)) && fetchCount)
			{
				if (pin)
				{
					PIN_INFO pinInfo;
					if (SUCCEEDED(pin->QueryPinInfo(&pinInfo)))
					{
						if (pinInfo.dir == pinType)
						{
							char pinName[128];
							::WideCharToMultiByte(CP_ACP, 0, pinInfo.achName, -1,
								pinName, 128, NULL, NULL);
							if (::strstr(pinName, inPinName))
							{
								foundPin = pin;
							}
						}
						pinInfo.pFilter->Release();

					}
					if (!foundPin)
					{
						pin->Release();
					}
					pin = 0;
				}
			}
			pinEnum->Release();
		}
	}

	// We don't keep outstanding reference count
	if (foundPin)
	{
		foundPin->Release();
	}
	return foundPin;
}

// --- IDistributorNotify methods ---
STDMETHODIMP CMPEG1Builder::NotifyGraphChange(void)
{
	return S_OK;
}

STDMETHODIMP CMPEG1Builder::Pause(void)
{
	return S_OK;
}

STDMETHODIMP CMPEG1Builder::Run(REFERENCE_TIME tStart)
{
	return S_OK;
}

STDMETHODIMP CMPEG1Builder::Stop(void)
{
	return S_OK;
}

STDMETHODIMP CMPEG1Builder::SetSyncSource(IReferenceClock *pClock)
{
	return S_OK;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -