#include <DShow.h> #include <InitGuid.h> #pragma comment(lib,"strmiids.lib") #pragma comment(lib,"quartz.lib") 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; } }