?? cmpeg1builder.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 + -