声明:欢迎任何人和组织转载本blog中文章,但必须标记文章原始链接和作者信息。
本文链接:http://blog.csdn.net/li_007/archive/2010/03/02/5338976.aspx
开拓进取的小乌龟------->CSDN点滴点点滴滴Blog
废话就少说了,把这段时间做的某***活动要用播发器的部分Directshow代码发出来,方便大家使用(声明:遵循LGPL协议)。本来同事想用openframeworks使用quicktime来播放这个3084*720的高清AD片子的,可是播放的时候有点卡,所以没办法就只有再次自己用directshow来写,现在分享的代码可以方便大家直接使用,做一个简单的播放器。
- //
- // CHDPlayerCore.h
- //
- // Written by Leezhm, 3rd Feb, 2010
- // Contact : Leezhm@luxoom.cn
- // Last Modified by Leezhm, 3rd Feb, 2010
- //
- #ifndef __CHDPlayerCore_h__
- #define __CHDPlayerCore_h__
- #include <DShow.h>
- #include <D3D9.h>
- #include <vmr9.h>
- #include "dshowutil.h"
- // Filter graph notification to the specified window
- #define WM_GRAPHNOTIFY (WM_USER+20)
- class CHDPlayerCore
- {
- public:
- CHDPlayerCore(void);
- virtual ~CHDPlayerCore(void);
- public:
- HRESULT CreateGraph(HWND hWnd);
- HRESULT RenderMovieFile(const wchar_t * file, bool bRenderAudio);
- bool RunMovies(void);
- bool StopMovies(void);
- bool PauseMovies(void);
- HRESULT GetNativeMovieSize(CRect & pos);
- HRESULT SetMoviePosition(CRect & pos);
- HRESULT GetMoviePosotion(CRect & pos);
- // IMediaSeeking
- HRESULT GetCurrentPosition(double * outPosition);
- HRESULT GetStopPosition(double * outPosition);
- HRESULT SetCurrentPosition(double inPosition);
- HRESULT SetStartStopPosition(double inStart, double inStop);
- HRESULT GetDuration(double * outDuration);
- HRESULT SetPlaybackRate(double inRate);
- HRESULT SetNotifyWindow(HWND inWindows);
- void HandleEvent(WPARAM wParam, LPARAM lParam);
- IMediaEventEx * GetEventHandle() const;
- OAFilterState GetCurrentState();
- private:
- inline void SafeRelease(IUnknown * filter)
- {
- if (NULL != filter)
- {
- filter->Release();
- filter = NULL;
- }
- }
- HRESULT GetInterface();
- HRESULT UsedVideoMixingRenderer9();
- BOOL IsWindowsMediaFile(const WCHAR *lpszFile);
- HRESULT GetUnconnectedPin(IBaseFilter *pFilter, PIN_DIRECTION PinDir, IPin **ppPin);
- HRESULT RenderMoivesToVMR9(IGraphBuilder * pGB, const WCHAR * wFileName, BOOL bRenderAudio);
- HRESULT AddToRot(IUnknown *pUnkGraph, DWORD *pdwRegister);
- void RemoveFromRot(DWORD pdwRegister);
- void ShowMsg(TCHAR *szFormat, ...);
- IBaseFilter* CreateEncodec(CString inFriendlyName);
- HRESULT CreateFilter(REFCLSID clsid, IBaseFilter **ppFilter);
- private:
- IGraphBuilder * pGraphBuilder;
- IMediaControl * pMediaControl;
- IMediaSeeking * pMediaSeeking;
- IMediaEventEx * pMediaEventEx;
- IBaseFilter * pVMR9;
- IVMRWindowlessControl9 * pVMR9Control;
- DWORD dwRegister;
- HWND mPlayerHandle;
- };
- #endif // __CHDPlayerCore_h__
- //
- // CHDPlayerCore.cpp
- //
- // Written by Leezhm, 3rd Feb, 2010
- // Contact : Leezhm@luxoom.cn
- // Last Modified by Leezhm, 3rd Feb, 2010
- //
- #include "StdAfx.h"
- #include "HDPlayerCore.h"
- CHDPlayerCore::CHDPlayerCore(void)
- {
- pGraphBuilder = NULL;
- pMediaControl = NULL;
- pMediaSeeking = NULL;
- pVMR9Control = NULL;
- pMediaEventEx = NULL;
- pVMR9 = NULL;
- }
- CHDPlayerCore::~CHDPlayerCore(void)
- {
- #ifdef _DEBUG
- RemoveFromRot(dwRegister);
- #endif
- SafeRelease(pMediaSeeking);
- SafeRelease(pMediaControl);
- SafeRelease(pVMR9Control);
- SafeRelease(pMediaEventEx);
- SafeRelease(pVMR9);
- SafeRelease(pGraphBuilder);
- CoUninitialize();
- }
- HRESULT CHDPlayerCore::CreateGraph(HWND hWnd)
- {
- HRESULT hr = NOERROR;
- mPlayerHandle = hWnd;
- if(S_OK != CoInitializeEx(NULL,COINIT_APARTMENTTHREADED))
- {
- return E_FAIL;
- }
- if (NULL == pGraphBuilder)
- {
- hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,
- IID_IGraphBuilder, (void **)&pGraphBuilder);
- if (SUCCEEDED(hr))
- {
- hr |= pGraphBuilder->QueryInterface(IID_IMediaControl, (void **)&pMediaControl);
- hr |= pGraphBuilder->QueryInterface(IID_IMediaSeeking, (void **)&pMediaSeeking);
- hr |= pGraphBuilder->QueryInterface(IID_IMediaEventEx, (void **)&pMediaEventEx);
- if (FAILED(hr))
- {
- return hr;
- }
- }
- }
- UsedVideoMixingRenderer9();
- return hr;
- }
- HRESULT CHDPlayerCore::RenderMovieFile(const wchar_t * file, bool bRenderAudio)
- {
- if (NULL != file)
- {
- if (NULL == pGraphBuilder)
- {
- MessageBox(NULL, L"The IGraphBuilder is NULL", L"Error Information", S_OK);
- }
- HRESULT hr = RenderMoivesToVMR9(pGraphBuilder, file, bRenderAudio);
- CRect rc;
- SetRect(&rc, 0, 0, 0, 0);
- hr |= GetNativeMovieSize(rc);
- hr |= SetMoviePosition(rc);
- if (SUCCEEDED(hr))
- {
- return hr;
- }
- }
- #ifdef _DEBUG
- AddToRot(pGraphBuilder, &dwRegister);
- #endif
- return E_FAIL;
- }
- bool CHDPlayerCore::RunMovies()
- {
- if (NULL != pGraphBuilder && NULL != pMediaControl)
- {
- if (State_Paused == GetCurrentState() || State_Stopped == GetCurrentState())
- {
- if (SUCCEEDED(pMediaControl->Run()))
- {
- return true;
- }
- else
- {
- return false;
- }
- }
- }
- return false;
- }
- bool CHDPlayerCore::StopMovies()
- {
- if (NULL != pGraphBuilder && NULL != pMediaControl)
- {
- if (State_Running == GetCurrentState())
- {
- if (SUCCEEDED(pMediaControl->Stop()))
- {
- return true;
- }
- else
- {
- return false;
- }
- }
- }
- return false;
- }
- bool CHDPlayerCore::PauseMovies()
- {
- if (NULL != pGraphBuilder && NULL != pMediaControl)
- {
- if (State_Running == GetCurrentState())
- {
- if (SUCCEEDED(pMediaControl->Pause()))
- {
- return true;
- }
- else
- {
- return false;
- }
- }
- }
- return false;
- }
- HRESULT CHDPlayerCore::GetNativeMovieSize(CRect & pos)
- {
- HRESULT hr = NOERROR;
- if (NULL != pVMR9Control)
- {
- hr = pVMR9Control->GetNativeVideoSize(&pos.right, &pos.bottom, NULL, NULL);
- if (SUCCEEDED(hr))
- {
- return hr;
- }
- SetRect(&pos, 0, 0, 0, 0);
- }
- return E_FAIL;
- }
- HRESULT CHDPlayerCore::GetMoviePosotion(CRect & pos)
- {
- HRESULT hr = NOERROR;
- CRect src;
- if (NULL != pVMR9Control)
- {
- hr = pVMR9Control->GetVideoPosition(&src, &pos);
- if (SUCCEEDED(hr))
- {
- return hr;
- }
- SetRect(&pos, 0, 0, 0, 0);
- }
- return E_FAIL;
- }
- HRESULT CHDPlayerCore::SetMoviePosition(CRect & pos)
- {
- HRESULT hr = NOERROR;
- if (NULL != pVMR9Control)
- {
- hr = pVMR9Control->SetVideoPosition(NULL, &pos);
- if (SUCCEEDED(hr))
- {
- return hr;
- }
- }
- return E_FAIL;
- }
- HRESULT CHDPlayerCore::GetCurrentPosition(double * outPosition)
- {
- HRESULT hr = E_FAIL;
- if (NULL != pMediaSeeking)
- {
- __int64 position = (__int64)0.0;
- hr = pMediaSeeking->GetCurrentPosition(&position);
- if (SUCCEEDED(hr))
- {
- *outPosition = ((double)position) / 10000000.0;
- return hr;
- }
- }
- return hr;
- }
- HRESULT CHDPlayerCore::GetStopPosition(double *outPosition)
- {
- HRESULT hr = E_FAIL;
- if (NULL != pMediaSeeking)
- {
- __int64 position = (__int64)0.0;
- hr = pMediaSeeking->GetStopPosition(&position);
- if (SUCCEEDED(hr))
- {
- *outPosition = ((double)position) / 10000000.0;
- return hr;
- }
- }
- return hr;
- }
- HRESULT CHDPlayerCore::SetCurrentPosition(double inPosition)
- {
- HRESULT hr = E_FAIL;
- if (NULL != pMediaSeeking)
- {
- __int64 position = (__int64)(10000000 * inPosition);
- hr = pMediaSeeking->SetPositions(&position, AM_SEEKING_AbsolutePositioning |
- AM_SEEKING_SeekToKeyFrame, 0, AM_SEEKING_NoPositioning);
- if (SUCCEEDED(hr))
- {
- return hr;
- }
- }
- return hr;
- }
- HRESULT CHDPlayerCore::SetStartStopPosition(double inStart, double inStop)
- {
- HRESULT hr = E_FAIL;
- if (NULL != pMediaSeeking)
- {
- __int64 start = (__int64)(10000000 * inStart);
- __int64 stop = (__int64)(10000000 * inStop);
- hr = pMediaSeeking->SetPositions(&start, AM_SEEKING_AbsolutePositioning | AM_SEEKING_SeekToKeyFrame,
- &stop, AM_SEEKING_AbsolutePositioning | AM_SEEKING_SeekToKeyFrame);
- if (SUCCEEDED(hr))
- {
- return hr;
- }
- }
- return hr;
- }
- HRESULT CHDPlayerCore::GetDuration(double * outDuration)
- {
- HRESULT hr = E_FAIL;
- if (NULL != pMediaSeeking)
- {
- __int64 length = (__int64)0.0;
- hr = pMediaSeeking->GetDuration(&length);
- if (SUCCEEDED(hr))
- {
- *outDuration = ((double)length / 10000000.0);
- return hr;
- }
- }
- return hr;
- }
- HRESULT CHDPlayerCore::SetPlaybackRate(double inRate)
- {
- HRESULT hr = E_FAIL;
- if (NULL != pMediaSeeking)
- {
- hr = pMediaSeeking->SetRate(inRate);
- if (SUCCEEDED(hr))
- {
- return hr;
- }
- }
- return hr;
- }
- HRESULT CHDPlayerCore::SetNotifyWindow(HWND inWindows)
- {
- HRESULT hr = E_FAIL;
- if (NULL != pMediaEventEx)
- {
- hr = pMediaEventEx->SetNotifyWindow((OAHWND)inWindows, WM_GRAPHNOTIFY, 0);
- if (SUCCEEDED(hr))
- {
- return hr;
- }
- }
- return hr;
- }
- void CHDPlayerCore::HandleEvent(WPARAM wParam, LPARAM lParam)
- {
- if (NULL != pMediaEventEx)
- {
- LONG eventCode = 0;
- LONG_PTR eventParam1 = 0;
- LONG_PTR eventParam2 = 0;
- while(SUCCEEDED(pMediaEventEx->GetEvent(&eventCode, &eventParam1, &eventParam2, 0)))
- {
- pMediaEventEx->FreeEventParams(eventCode, eventParam1, eventParam2);
- switch (eventCode)
- {
- case EC_COMPLETE:
- break;
- case EC_USERABORT:
- case EC_ERRORABORT:
- break;
- default:
- break;
- }
- }
- }
- }
- IMediaEventEx * CHDPlayerCore::GetEventHandle() const
- {
- if (NULL != pMediaEventEx)
- {
- return pMediaEventEx;
- }
- return NULL;
- }
- HRESULT CHDPlayerCore::UsedVideoMixingRenderer9()
- {
- HRESULT hr = NOERROR;
- hr |= CoCreateInstance(CLSID_VideoMixingRenderer9, NULL, CLSCTX_INPROC,
- IID_IBaseFilter, (void **)&pVMR9);
- if (SUCCEEDED(hr))
- {
- hr |= pGraphBuilder->AddFilter(pVMR9, L"Video Mixing Render 9");
- if (SUCCEEDED(hr))
- {
- IVMRFilterConfig9 * pConfig9 = NULL;
- hr |= pVMR9->QueryInterface(IID_IVMRFilterConfig9, (void **)&pConfig9);
- if (SUCCEEDED(hr))
- {
- hr |= pConfig9->SetNumberOfStreams(2);
- hr |= pConfig9->SetRenderingMode(VMR9Mode_Windowless);
- hr |= pConfig9->SetRenderingPrefs(RenderPrefs_AllowOverlays);
- pConfig9->Release();
- }
- pConfig9 = NULL;
- IVMRMonitorConfig9 * pMonitorConfig = NULL;
- hr |= pVMR9->QueryInterface(IID_IVMRMonitorConfig9, (void **)&pMonitorConfig);
- if(SUCCEEDED(hr))
- {
- UINT iCurrentMonitor;
- hr |= pMonitorConfig->GetMonitor(&iCurrentMonitor);
- pMonitorConfig->Release();
- }
- pMonitorConfig = NULL;
- hr |= pVMR9->QueryInterface(IID_IVMRWindowlessControl9, (void **)&pVMR9Control);
- }
- }
- SafeRelease(pVMR9);
- if (SUCCEEDED(hr))
- {
- hr |= pVMR9Control->SetVideoClippingWindow(mPlayerHandle);
- hr |= pVMR9Control->SetAspectRatioMode(VMR_ARMODE_LETTER_BOX);
- }
- else
- {
- SafeRelease(pVMR9Control);
- }
- return hr;
- }
- HRESULT CHDPlayerCore::RenderMoivesToVMR9(IGraphBuilder * pGB, const WCHAR * wFileName, BOOL bRenderAudio = TRUE)
- {
- HRESULT hr = NOERROR;
- CComPtr <IPin> pOutputPin;
- CComPtr <IPin> pInputPin;
- CComPtr <IBaseFilter> pSource;
- CComPtr <IBaseFilter> pAudioRenderer;
- CComPtr <IFilterGraph2> pFG;
- CComPtr <IFileSourceFilter> pFileSource;
- // Render audio if requested (defaults to TRUE)
- if (bRenderAudio)
- {
- // Because we will be rendering with the RENDERTOEXISTINGRENDERERS flag,
- // we need to create an audio renderer and add it to the graph.
- // Create an instance of the DirectSound renderer (for each media file).
- //
- // Note that if the system has no sound card (or if the card is disabled),
- // then creating the DirectShow renderer will fail. In that case,
- // handle the failure quietly.
- if (SUCCEEDED(CoCreateInstance(CLSID_DSoundRender, NULL, CLSCTX_INPROC_SERVER,
- IID_IBaseFilter, (void **)&pAudioRenderer)))
- {
- // The audio renderer was successfully created, so add it to the graph
- hr |= pGB->AddFilter(pAudioRenderer, L"Audio Renderer");
- if (FAILED(hr))
- {
- return hr;
- }
- }
- }
- // Add a file source filter for this media file
- if (!IsWindowsMediaFile(wFileName))
- {
- // Add the source filter to the graph
- if (FAILED(hr |= pGB->AddSourceFilter(wFileName, L"SOURCE", &pSource)))
- {
- USES_CONVERSION;
- WCHAR szMsg[MAX_PATH + 128] = {0};
- hr = StringCchPrintf(szMsg, NUMELMS(szMsg), TEXT("Failed to add the source filter to the graph! hr=0x%x/r/n/r/n")
- TEXT("Filename: %s/0"), hr, wFileName);
- MessageBox(NULL, szMsg, TEXT("Failed to render file to VMR9"), MB_OK | MB_ICONERROR);
- return hr;
- }
- hr |= GetUnconnectedPin(pSource, PINDIR_OUTPUT, &pOutputPin);
- if (FAILED(hr))
- {
- return hr;
- }
- // Get an IFilterGraph2 interface to assist in building the
- // multifile graph with the non-default VMR9 renderer
- hr |= pGB->QueryInterface(IID_IFilterGraph2, (void **)&pFG);
- if (FAILED(hr))
- {
- return hr;
- }
- // Render the output pin, using the VMR9 as the specified renderer. This is
- // necessary in case the GraphBuilder needs to insert a Color Space convertor,
- // or if multiple filters insist on using multiple allocators.
- // The audio renderer will also be used, if the media file contains audio.
- hr |= pFG->RenderEx(pOutputPin, AM_RENDEREX_RENDERTOEXISTINGRENDERERS, NULL);
- if (FAILED(hr))
- {
- return hr;
- }
- // If this media file does not contain an audio stream, then the
- // audio renderer that we created will be unconnected. If left in the
- // graph, it could interfere with rate changes and timing.
- // Therefore, if the audio renderer is unconnected, remove it from the graph.
- if (pAudioRenderer != NULL)
- {
- IPin *pUnconnectedPin=0;
- // Is the audio renderer's input pin connected?
- HRESULT hrPin = GetUnconnectedPin(pAudioRenderer, PINDIR_INPUT, &pUnconnectedPin);
- // If there is an unconnected pin, then remove the unused filter
- if (SUCCEEDED(hrPin) && (pUnconnectedPin != NULL))
- {
- // Release the returned IPin interface
- pUnconnectedPin->Release();
- // Remove the audio renderer from the graph
- hrPin = pGB->RemoveFilter(pAudioRenderer);
- }
- }
- }
- else
- {
- // Load the improved ASF reader filter by CLSID
- hr |= CreateFilter(CLSID_WMAsfReader, &pSource);
- if(FAILED(hr))
- {
- ShowMsg(TEXT("Failed to create WMAsfWriter filter! hr=0x%x/0"), hr);
- return hr;
- }
- // Add the ASF reader filter to the graph. For ASF/WMV/WMA content,
- // this filter is NOT the default and must be added explicitly.
- hr |= pGB->AddFilter(pSource, L"WMV ASF Reader");
- if(FAILED(hr))
- {
- ShowMsg(TEXT("Failed to add ASF reader filter to graph! hr=0x%x/0"), hr);
- return hr;
- }
- // Set its source filename
- hr |= pSource->QueryInterface(IID_IFileSourceFilter, (void **) &pFileSource);
- // Attempt to load this file
- hr |= pFileSource->Load(wFileName, NULL);
- if (FAILED(hr))
- {
- ShowMsg(TEXT("Failed to load file in source filter (pFileSource->Load())! hr=0x%x/0"), hr);
- return hr;
- }
- ULONG count = 0;
- CountTotalFilterPins(pSource, &count);
- for (ULONG i = 0; i < count; i ++)
- {
- pOutputPin = GetOutPin(pSource, i);
- PIN_INFO info;
- pOutputPin->QueryPinInfo(&info);
- CComPtr<IBaseFilter> Codec;
- if (_tcsstr(info.achName, TEXT("Video")))
- {
- Codec = CreateEncodec(_T("WMVideo Decoder DMO"));
- if (NULL != pGraphBuilder)
- {
- pGraphBuilder->AddFilter(Codec, _T("WMVideo Decoder DMO"));
- pInputPin = GetInPin(Codec, 0);
- hr |= pGraphBuilder->Connect(pOutputPin, pInputPin);
- if (FAILED(hr))
- {
- ShowMsg(_T("Video Connected Failed. hr=0x%x/0"), hr);
- return hr;
- }
- pOutputPin = GetOutPin(Codec, 0);
- pInputPin = GetInPin(pVMR9, 0);
- hr |= pGraphBuilder->Connect(pOutputPin, pInputPin);
- if (FAILED(hr))
- {
- ShowMsg(_T("Video Connected Failed. hr=0x%x/0"), hr);
- return hr;
- }
- }
- }
- else if (_tcsstr(info.achName, TEXT("Audio")))
- {
- Codec = CreateEncodec(_T("WMAudio Decoder DMO"));
- if (NULL != pGraphBuilder)
- {
- pGraphBuilder->AddFilter(Codec, _T("WMAudio Decoder DMO"));
- pInputPin = GetInPin(Codec, 0);
- hr |= pGraphBuilder->Connect(pOutputPin, pInputPin);
- if (FAILED(hr))
- {
- ShowMsg(_T("Audio Connected Failed. hr=0x%x/0"), hr);
- return hr;
- }
- pOutputPin = GetOutPin(Codec, 0);
- if (NULL == pAudioRenderer)
- {
- if (SUCCEEDED(CoCreateInstance(CLSID_DSoundRender, NULL, CLSCTX_INPROC_SERVER,
- IID_IBaseFilter, (void **)&pAudioRenderer)))
- {
- // The audio renderer was successfully created, so add it to the graph
- hr |= pGB->AddFilter(pAudioRenderer, L"Audio Renderer");
- if (FAILED(hr))
- {
- return hr;
- }
- }
- }
- pInputPin = GetInPin(pAudioRenderer, 0);
- hr |= pGraphBuilder->Connect(pOutputPin, pInputPin);
- if (FAILED(hr))
- {
- ShowMsg(_T("Audio Connected Failed. hr=0x%x/0"), hr);
- return hr;
- }
- }
- }
- }
- }
- return hr;
- }
- BOOL CHDPlayerCore::IsWindowsMediaFile(const WCHAR *lpszFile)
- {
- USES_CONVERSION;
- WCHAR szFilename[MAX_PATH] = {0};
- // Copy the file name to a local string and convert to lowercase
- (void)StringCchCopy(szFilename,NUMELMS(szFilename), lpszFile);
- szFilename[MAX_PATH-1] = 0;
- _tcslwr_s(szFilename, 260);
- if (_tcsstr(szFilename, TEXT(".asf")) ||
- _tcsstr(szFilename, TEXT(".wma")) ||
- _tcsstr(szFilename, TEXT(".wmv")))
- {
- return TRUE;
- }
- else
- {
- return FALSE;
- }
- }
- OAFilterState CHDPlayerCore::GetCurrentState()
- {
- OAFilterState states = 0;
- if (NULL != pGraphBuilder && NULL != pMediaControl)
- {
- pMediaControl->GetState(INFINITE, &states);
- }
- return states;
- }
- //Register the filter graph to Rot
- HRESULT CHDPlayerCore::AddToRot(IUnknown *pUnkGraph, DWORD *pdwRegister)
- {
- HRESULT hr = NOERROR;
- IMoniker * pMoniker = NULL;
- IRunningObjectTable * pROT = NULL;
- if(FAILED(GetRunningObjectTable(0,&pROT)))
- {
- return E_FAIL;
- }
- WCHAR wsz[256];
- ::memset(wsz,0,256);
- hr = StringCchPrintfW(wsz, NUMELMS(wsz), L"FilterGraph %08x pid %08x",
- (DWORD_PTR)pUnkGraph,GetCurrentProcessId());
- hr = CreateItemMoniker(L"!",wsz,&pMoniker);
- if(SUCCEEDED(hr))
- {
- hr = pROT->Register(0,pUnkGraph,pMoniker,pdwRegister);
- pMoniker->Release();
- }
- pROT->Release();
- return hr;
- }
- void CHDPlayerCore::RemoveFromRot(DWORD pdwRegister)
- {
- IRunningObjectTable *pROT = NULL;
- if(SUCCEEDED(GetRunningObjectTable(0,&pROT)))
- {
- pROT->Revoke(pdwRegister);
- pROT->Release();
- }
- }
- HRESULT CHDPlayerCore::GetUnconnectedPin(
- IBaseFilter *pFilter, // Pointer to the filter.
- PIN_DIRECTION PinDir, // Direction of the pin to find.
- IPin **ppPin) // Receives a pointer to the pin.
- {
- IEnumPins *pEnum = 0;
- IPin *pPin = 0;
- if (!ppPin)
- return E_POINTER;
- *ppPin = 0;
- // Get a pin enumerator
- HRESULT hr = pFilter->EnumPins(&pEnum);
- if (FAILED(hr))
- return hr;
- // Look for the first unconnected pin
- while (pEnum->Next(1, &pPin, NULL) == S_OK)
- {
- PIN_DIRECTION ThisPinDir;
- pPin->QueryDirection(&ThisPinDir);
- if (ThisPinDir == PinDir)
- {
- IPin *pTmp = 0;
- hr = pPin->ConnectedTo(&pTmp);
- if (SUCCEEDED(hr)) // Already connected, not the pin we want.
- {
- pTmp->Release();
- }
- else // Unconnected, this is the pin we want.
- {
- pEnum->Release();
- *ppPin = pPin;
- return S_OK;
- }
- }
- pPin->Release();
- }
- // Release the enumerator
- pEnum->Release();
- // Did not find a matching pin
- return E_FAIL;
- }
- IBaseFilter* CHDPlayerCore::CreateEncodec(CString inFriendlyName)
- {
- HRESULT hr = NOERROR;
- ICreateDevEnum * enumHardware =NULL;
- IBaseFilter * hardwareFilter = NULL;
- hr = CoCreateInstance(CLSID_SystemDeviceEnum,NULL,CLSCTX_INPROC_SERVER,
- IID_ICreateDevEnum,(void **)&enumHardware);
- if(FAILED(hr))
- {
- return NULL;
- }
- IEnumMoniker * enumMoniker = NULL;
- hr = enumHardware->CreateClassEnumerator(CLSID_LegacyAmFilterCategory, &enumMoniker,0);
- if(FAILED(hr))
- {
- return NULL;
- }
- if(enumMoniker)
- {
- enumMoniker->Reset();
- IMoniker * moniker = NULL;
- char friendlyName[256];
- ZeroMemory(friendlyName,256);
- while(S_OK == enumMoniker->Next(1,&moniker,0))
- {
- if(moniker)
- {
- IPropertyBag * proBag = NULL;
- VARIANT name;
- hr = moniker->BindToStorage(NULL,NULL,IID_IPropertyBag,(void **)&proBag);
- if(SUCCEEDED(hr))
- {
- name.vt = VT_BSTR;
- proBag->Read(L"FriendlyName",&name,NULL);
- }
- if(SUCCEEDED(hr))
- {
- WideCharToMultiByte(CP_ACP, 0, name.bstrVal, -1,friendlyName, 256,
- NULL, NULL);
- CString str = (CString)friendlyName;
- if(inFriendlyName == str)
- {
- moniker->BindToObject(NULL,NULL,IID_IBaseFilter,
- (void **)&hardwareFilter);
- }
- }
- if(proBag)
- {
- proBag->Release();
- proBag = NULL;
- }
- moniker->Release();
- }
- }
- enumMoniker->Release();
- }
- enumHardware->Release();
- return hardwareFilter;
- }
- HRESULT CHDPlayerCore::CreateFilter(REFCLSID clsid, IBaseFilter **ppFilter)
- {
- HRESULT hr;
- hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER,
- IID_IBaseFilter,
- (void **) ppFilter);
- if(FAILED(hr))
- {
- //MessageBox(TEXT("CreateFilter: Failed to create filter! hr=0x%x/n"));
- if (ppFilter)
- *ppFilter = NULL;
- return hr;
- }
- return S_OK;
- }
- void CHDPlayerCore::ShowMsg(TCHAR *szFormat, ...)
- {
- TCHAR szBuffer[1024]; // Large buffer for long filenames or URLs
- const size_t NUMCHARS = sizeof(szBuffer) / sizeof(szBuffer[0]);
- const int LASTCHAR = NUMCHARS - 1;
- // Format the input string
- va_list pArgs;
- va_start(pArgs, szFormat);
- // Use a bounded buffer size to prevent buffer overruns. Limit count to
- // character size minus one to allow for a NULL terminating character.
- (void)StringCchVPrintf(szBuffer, NUMCHARS - 1, szFormat, pArgs);
- va_end(pArgs);
- // Ensure that the formatted string is NULL-terminated
- szBuffer[LASTCHAR] = TEXT('/0');
- // Display a message box with the formatted string
- MessageBox(NULL, szBuffer, TEXT("Porsche HD Player"), MB_OK);
- }
使用示例代码
- if (NULL == this->player)
- {
- this->player = new CHDPlayerCore();
- }
- this->player->CreateGraph(this->playerDlg->GetSafeHwnd());
- this->player->RenderMovieFile(filePaths, true);
- this->player->SetNotifyWindow(this->GetSafeHwnd());
- this->player->SetStartStopPosition(0, 117.006);
- this->player->RunMovies();
其实封装好了,使用起来很简单的,我想应该可以方便大家使用,完成一个简单的播放器。当然还可以监听播放器事件,那段代码就没必要贴出来的,很简单,MSDN上就有的