CMPEG1Builder.cpp
上传用户:tuheem
上传日期:2007-05-01
资源大小:21889k
文件大小:7k
- //
- // 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;
- }