DEFINE_GUID(CLSID_RealSource,0x61a33c2a, 0x42dd, 0x4b40, 0x83, 0x8f, 0xe2, 0xf3, 0x5a, 0xc9, 0x96, 0x6a); // {61A33C2A-42DD-4b40-838F-E2F35AC9966A}
DEFINE_GUID(CLSID_RealVideoDecoder,0x97e3783, 0x8f17, 0x43b3, 0x8d, 0x77, 0x9a, 0x37, 0x34, 0x53, 0x98, 0x10); // {097E3783-8F17-43b3-8D77-9A3734539810}
DEFINE_GUID(CLSID_RealAudioDecoder,0xe5241d26, 0x8677, 0x40c5, 0xaa, 0x5d, 0xa1, 0x1a, 0x66, 0xe5, 0x22, 0xe6); // {E5241D26-8677-40c5-AA5D-A11A66E522E6}
BOOL IsCanConnectPin(IPin *pPin,PIN_DIRECTION dir)
{
PIN_INFO pi;
if(FAILED(pPin->QueryPinInfo(&pi)))
return FALSE;
else if(pi.pFilter)
pi.pFilter->Release();
if(pi.dir != dir)
return FALSE;
CComPtr<IPin> pPinTo;
return !SUCCEEDED(pPin->ConnectedTo(&pPinTo));
}
HRESULT ConnectFilter(IBaseFilter* pFilterOut,IBaseFilter* pFilterIn)
{
HRESULT hr = E_FAIL;
if(!pFilterIn || !pFilterOut)
return E_POINTER;
FILTER_INFO fi;
if(SUCCEEDED(pFilterOut->QueryFilterInfo(&fi)))
{
if(fi.pGraph)
{
fi.pGraph->Release();
CComPtr<IEnumPins>pEnumPins;
if(SUCCEEDED(pFilterOut->EnumPins(&pEnumPins)))
{
ULONG cFetched;
CComPtr<IPin> pPinOut;
for(int _index = 0; S_OK == pEnumPins->Next(1,&pPinOut,&cFetched); _index++,pPinOut = NULL)
{
if(!IsCanConnectPin(pPinOut,PINDIR_OUTPUT))
continue;
CComPtr<IEnumPins>pEnumPins;
if(SUCCEEDED(pFilterIn->EnumPins(&pEnumPins)))
{
ULONG cFetched;
CComPtr<IPin> pPinIn;
for(int _index = 0; S_OK == pEnumPins->Next(1,&pPinIn,&cFetched);_index++,pPinIn = NULL)
{
if(IsCanConnectPin(pPinIn,PINDIR_INPUT))
{
try
{
hr = fi.pGraph->ConnectDirect(pPinOut,pPinIn,0);
}
catch(...)
{
hr = E_FAIL;
}
if(SUCCEEDED(hr))
return S_OK;
}
}
}
}
}
}
}
return E_FAIL;
}
HRESULT AddToRot(IUnknown *pUnkGraph,DWORD *pdwResgister)
{
IMoniker *pMoniker = NULL;
IRunningObjectTable *pROT = NULL;
if(FAILED(GetRunningObjectTable(0,&pROT)))
return E_FAIL;
WCHAR wsz[MAX_PATH] = {0};
wsprintfW(wsz,L"FilterGraph %08x pid %08x",(DWORD_PTR)pUnkGraph,GetCurrentProcessId());
HRESULT hr = CreateItemMoniker(L"!",wsz,&pMoniker);
if(SUCCEEDED(hr))
{
hr = pROT->Register(ROTFLAGS_REGISTRATIONKEEPSALIVE,pUnkGraph,pMoniker,pdwResgister);
}
pROT->Release();
return hr;
}
void CDShowDlg::OnBnClickedPlay()
{
if(m_strFileName.IsEmpty())
{
MessageBox(L"请选择一个文件",L"提示");
return;
}
CoInitialize(NULL);
CComPtr<IGraphBuilder>m_spGB;
m_spGB.CoCreateInstance(CLSID_FilterGraph,0,CLSCTX_INPROC_SERVER);
if(m_spGB)
{
DWORD dwRegister;
AddToRot(m_spGB,&dwRegister);
CComPtr<IBaseFilter>spSource;
spSource.CoCreateInstance(CLSID_RealSource,0,CLSCTX_INPROC_SERVER);
CComPtr<IBaseFilter>spVideoDecoder;
spVideoDecoder.CoCreateInstance(CLSID_RealVideoDecoder,0,CLSCTX_INPROC_SERVER);
CComPtr<IBaseFilter>spAudioDecoder;
spAudioDecoder.CoCreateInstance(CLSID_RealAudioDecoder,0,CLSCTX_INPROC_SERVER);
CComPtr<IBaseFilter>spVideoRender;
spVideoRender.CoCreateInstance(CLSID_VideoMixingRenderer,0,CLSCTX_INPROC_SERVER);
CComPtr<IBaseFilter>spAudioRender;
spAudioRender.CoCreateInstance(CLSID_DSoundRender,0,CLSCTX_INPROC_SERVER);
if(spSource && spAudioDecoder && spVideoDecoder && spAudioRender && spVideoRender)
{
m_spGB->AddFilter(spSource,L"Source");
m_spGB->AddFilter(spVideoDecoder,L"VideoDecoder");
m_spGB->AddFilter(spAudioDecoder,L"AudioDecoder");
m_spGB->AddFilter(spVideoRender,L"VideoRender");
m_spGB->AddFilter(spAudioRender,L"AudioRender");
CComQIPtr<IFileSourceFilter>spFileSource(spSource);
if(spFileSource)
{
if(S_OK == spFileSource->Load(m_strFileName,0))
{
ConnectFilter(spSource,spVideoDecoder);
ConnectFilter(spSource,spAudioDecoder);
ConnectFilter(spVideoDecoder,spVideoRender);
ConnectFilter(spAudioDecoder,spAudioRender);
}
}
{
CComQIPtr<IVideoWindow>spVideoWnd(m_spGB);
if(spVideoWnd)
{
spVideoWnd->put_Owner((OAHWND)this->GetSafeHwnd());
spVideoWnd->put_WindowStyle(WS_CHILD|WS_CLIPSIBLINGS|WS_CLIPCHILDREN|WS_VISIBLE);
spVideoWnd->put_WindowStyleEx(WS_EX_NOPARENTNOTIFY);
CRect rt;
GetClientRect(&rt);
spVideoWnd->SetWindowPosition(0,0,rt.Width(),rt.Height());
}
CComQIPtr<IMediaControl>spControl(m_spGB);
if(spControl)
spControl->Run();
}
}
}
CoUninitialize;
}
void CDShowDlg::OnBnClickedBrowser()
{
CFileDialog dlg(TRUE,NULL,NULL,0,L"All File(*.*)|*.*");
if(IDOK == dlg.DoModal())
{
CString strFileName = dlg.GetPathName();
SetDlgItemText(IDC_FILENAME,strFileName);
m_strFileName = strFileName;
}
}