我将有关Media Foundation的函数调用封装到一个类CSpsPlayer中了,CSpsPlayer类的使用方法如下:
1)CSpsPlayer* pPlayer = new CSpsPlayer(hWndPlay);
2)pPlayer->OpenFile("c:\\ttt.asf");
3)获取视频时长pPlayer->GetTimeLen();单位是1/10^4毫秒;
4)pPlayer->Play();
5)暂定pPlayer->Pause();
6)暂停后继续pPlayer->Play();
7)获取播放位置pPlayer->GetCurrentPos();单位是1/10^4毫秒;
8)设置音量pPlayer->SetAudioVolumn(lVolumn);lVolumn取值是0~100
9)Seek操作pPlayer->Move(pos);pos单位是1/10^4毫秒;
10)播放窗口尺寸变化pPlayer->AdjustWindowPosition();
11)停止播放pPlayer->Stop();
12)关闭文件pPlayer->CloseFile();
SpsPlayer.h文件:
- //
- // Class: CSpsPlayer
- //
- // Compiler: Visual C++
- // Tested on: Visual C++ 2010
- //
- // Created: 08/March/2014
- //
- // Author: Liu Yang 464585657@qq.com
- //
- //
- #ifndef SPSPLAYER_H
- #define SPSPLAYER_H
- #include <Windows.h>
- #include <string>
- #include <vector>
- #include <new>
- #include <shobjidl.h>
- #include <shlwapi.h>
- #include <assert.h>
- #include <strsafe.h>
- // Media Foundation headers
- #include <mfapi.h>
- #include <mfidl.h>
- #include <mferror.h>
- #include <evr.h>
- #define SAFE_RELEASE(x) { if (x) x->Release(); x = NULL; }
- #define SAFE_CLOSE_HANDLE(x) { if (x)CloseHandle(x); x = NULL; }
- enum PlayerState//播放器状态
- {
- Closed = 0, // No session.
- Started, // Session is playing a file.
- Paused, // Session is paused.
- Stopped, // Session is stopped (ready to play).
- };
- class CMyCriticalSection
- {
- public:
- CMyCriticalSection()
- {
- ::InitializeCriticalSection(&m_cs);
- }
- virtual ~CMyCriticalSection()
- {
- ::DeleteCriticalSection(&m_cs);
- }
- void lock()
- {
- ::EnterCriticalSection(&m_cs);
- }
- void unlock()
- {
- ::LeaveCriticalSection(&m_cs);
- }
- private:
- CRITICAL_SECTION m_cs;
- };
- class CMyAutoLock
- {
- public:
- CMyAutoLock(CMyCriticalSection * pCrit)
- {
- m_pCrit = pCrit;
- m_pCrit->lock();
- }
- virtual ~CMyAutoLock()
- {
- m_pCrit->unlock();
- }
- private:
- CMyCriticalSection * m_pCrit;
- };
- class CSpsPlayer : public IMFAsyncCallback
- {
- public:
- CSpsPlayer(HWND hWndVideo);
- virtual ~CSpsPlayer();
- // IUnknown methods
- STDMETHODIMP QueryInterface(REFIID iid, void** ppv);
- STDMETHODIMP_(ULONG) AddRef();
- STDMETHODIMP_(ULONG) Release();
- // IMFAsyncCallback methods
- STDMETHODIMP GetParameters(DWORD*, DWORD*)
- {
- // Implementation of this method is optional.
- return E_NOTIMPL;
- }
- STDMETHODIMP Invoke(IMFAsyncResult* pAsyncResult);
- //播放控制函数
- std::string GetSpsFilePathName();//获取文件名
- BOOL OpenFile(const char * s);//打开文件
- BOOL CloseFile();//关闭文件
- long GetPlayStatus();//获取播放器状态,返回:0:停止;1:播放;2:暂停
- BOOL Play();//播放
- BOOL Pause();//暂停
- BOOL Stop();//停止
- LONGLONG GetTimeLen();//获取时长(单位是1/10^4毫秒)
- LONGLONG GetCurrentPos();//获取当前播放位置(单位是1/10^4毫秒)
- BOOL Move(LONGLONG pos);//跳到指定位置播放(单位是1/10^4毫秒)
- BOOL GetAudioIsOpenedOrClosed();//获取声音是开启还是关闭状态
- BOOL OpenOrCloseAudio(BOOL bOpen);//打开或关闭声音
- long GetAudioVolumn();//获取音量
- BOOL SetAudioVolumn(long lVolumn);//设置音量
- void AdjustWindowPosition();//播放窗口尺寸发生变化时调用
- void RepaitVideo();//暂停时,播放窗口重绘后调用
- private:
- BOOL AddBranchToTopology( IMFTopology *pTopology, IMFMediaSource *pSource, IMFPresentationDescriptor *pPD, DWORD iStream);//添加流的分支到topology
- IMFGetService* GetMFGetService();
- IMFSimpleAudioVolume* GetSimpleAudioVolume();
- IMFPresentationClock* GetPresentationClock();
- IMFVideoDisplayControl* GetVideoDisplayControl();
- private:
- CMyCriticalSection m_csCrit;//播放器锁
- HWND m_hWndVideo;//播放窗口
- std::string m_sSpsFileName;//视频文件
- //
- IMFMediaSession* m_pSession;//Media Session
- PlayerState m_state;//播放器状态
- LONGLONG m_llTimeLen;//1/10^4毫秒
- long m_nRefCount; // Reference count.
- };
- #endif
SpsPlayer.cpp文件:
- //
- // Class: CSpsPlayer
- //
- // Compiler: Visual C++
- // Tested on: Visual C++ 2010
- //
- // Created: 08/March/2014
- //
- // Author: Liu Yang 464585657@qq.com
- //
- //
- #include "SpsPlayer.h"
- #include <assert.h>
- #pragma comment(lib, "shlwapi")
- static const GUID MY_MR_VIDEO_RENDER_SERVICE ={0x1092a86c,0xab1a,0x459a, {0xa3, 0x36, 0x83, 0x1f, 0xbc, 0x4d, 0x11, 0xff} };
- CSpsPlayer::CSpsPlayer(HWND hWndVideo)
- {
- m_hWndVideo = hWndVideo;
- //
- m_pSession = NULL;
- m_state = Closed;
- m_llTimeLen = 0;
- }
- CSpsPlayer::~CSpsPlayer()
- {
- CloseFile();
- }
- HRESULT CSpsPlayer::QueryInterface(REFIID riid, void** ppv)
- {
- static const QITAB qit[] =
- {
- QITABENT(CSpsPlayer, IMFAsyncCallback),
- { 0 }
- };
- return QISearch(this, qit, riid, ppv);
- }
- ULONG CSpsPlayer::AddRef()
- {
- return InterlockedIncrement(&m_nRefCount);
- }
- ULONG CSpsPlayer::Release()
- {
- ULONG uCount = InterlockedDecrement(&m_nRefCount);
- if (uCount == 0)
- {
- delete this;
- }
- return uCount;
- }
- std::string CSpsPlayer::GetSpsFilePathName()
- {
- CMyAutoLock lock(&m_csCrit);
- return m_sSpsFileName;
- }
- BOOL CSpsPlayer::OpenFile(const char * s)
- {
- CloseFile();
- CMyAutoLock lock(&m_csCrit);
- std::string sSpsFileName;
- sSpsFileName = s;
- //初始化Media Foundataion平台
- HRESULT hr = MFStartup(MF_VERSION);
- if (FAILED(hr))
- {
- return FALSE;
- }
- //创建Media Session对象
- hr = MFCreateMediaSession(NULL, &m_pSession);
- if (FAILED(hr))
- {
- MFShutdown();
- return FALSE;
- }
- //开始从Media Session接收事件
- hr = m_pSession->BeginGetEvent((IMFAsyncCallback*)this, NULL);
- if (FAILED(hr))
- {
- SAFE_RELEASE(m_pSession);
- MFShutdown();
- return FALSE;
- }
- MF_OBJECT_TYPE ObjectType = MF_OBJECT_INVALID;
- IMFSourceResolver* pSourceResolver = NULL;//Media Source选择器
- IUnknown* pSource = NULL;
- IMFMediaSource* pMFMediaSource = NULL;
- //根据给定的文件路径,创建Media Source对象,并获取IMFMediaSource接口
- hr = MFCreateSourceResolver(&pSourceResolver);
- if (FAILED(hr))
- {
- SAFE_RELEASE(m_pSession);
- MFShutdown();
- return FALSE;
- }
- WCHAR szwFile[MAX_PATH] = {0};
- MultiByteToWideChar(CP_ACP, 0, sSpsFileName.c_str(), -1, szwFile, MAX_PATH);
- hr = pSourceResolver->CreateObjectFromURL( szwFile, MF_RESOLUTION_MEDIASOURCE, NULL, &ObjectType, &pSource );
- if (FAILED(hr))
- {
- SAFE_RELEASE(pSourceResolver);
- SAFE_RELEASE(m_pSession);
- MFShutdown();
- return FALSE;
- }
- hr = pSource->QueryInterface(IID_PPV_ARGS(&pMFMediaSource));
- if (FAILED(hr))
- {
- SAFE_RELEASE(pSource);
- SAFE_RELEASE(pSourceResolver);
- SAFE_RELEASE(m_pSession);
- MFShutdown();
- return FALSE;
- }
- SAFE_RELEASE(pSource);
- SAFE_RELEASE(pSourceResolver);
- IMFPresentationDescriptor* pSourcePD = NULL;
- //创建Presentation描述符
- hr = pMFMediaSource->CreatePresentationDescriptor(&pSourcePD);
- if (FAILED(hr))
- {
- SAFE_RELEASE(pMFMediaSource);
- SAFE_RELEASE(m_pSession);
- MFShutdown();
- return FALSE;
- }
- MFTIME mDuration = 0;
- hr = pSourcePD->GetUINT64(MF_PD_DURATION, (UINT64*)&mDuration);
- if (FAILED(hr))
- {
- SAFE_RELEASE(pSourcePD);
- SAFE_RELEASE(pMFMediaSource);
- SAFE_RELEASE(m_pSession);
- MFShutdown();
- return FALSE;
- }
- m_llTimeLen = mDuration;
- DWORD cSourceStreams = 0;
- //获取Media Source对象的流的数目
- hr = pSourcePD->GetStreamDescriptorCount(&cSourceStreams);
- if (FAILED(hr))
- {
- SAFE_RELEASE(pSourcePD);
- SAFE_RELEASE(pMFMediaSource);
- SAFE_RELEASE(m_pSession);
- MFShutdown();
- return FALSE;
- }
- IMFTopology *pTopology = NULL;
- //创建topology对象
- hr = MFCreateTopology(&pTopology);
- if (FAILED(hr))
- {
- SAFE_RELEASE(pSourcePD);
- SAFE_RELEASE(pMFMediaSource);
- SAFE_RELEASE(m_pSession);
- MFShutdown();
- return FALSE;
- }
- //为每一个流创建节点,并将节点添加到topology中
- for (DWORD i = 0; i < cSourceStreams; i++)
- {
- BOOL bRet = AddBranchToTopology(pTopology, pMFMediaSource, pSourcePD, i);
- if (!bRet)
- {
- SAFE_RELEASE(pTopology);
- SAFE_RELEASE(pSourcePD);
- SAFE_RELEASE(pMFMediaSource);
- SAFE_RELEASE(m_pSession);
- MFShutdown();
- return FALSE;
- }
- }
- //将topology对象设置到Media Session对象中
- hr = m_pSession->SetTopology(0, pTopology);
- if (FAILED(hr))
- {
- SAFE_RELEASE(pTopology);
- SAFE_RELEASE(pSourcePD);
- SAFE_RELEASE(pMFMediaSource);
- SAFE_RELEASE(m_pSession);
- MFShutdown();
- return FALSE;
- }
- m_sSpsFileName = sSpsFileName;
- m_state = Stopped;
- return TRUE;
- }
- BOOL CSpsPlayer::CloseFile()
- {
- Stop();
- CMyAutoLock lock(&m_csCrit);
- SAFE_RELEASE(m_pSession);
- MFShutdown();
- m_sSpsFileName = "";
- return TRUE;
- }
- long CSpsPlayer::GetPlayStatus()
- {
- CMyAutoLock lock(&m_csCrit);
- switch(m_state)
- {
- case Closed://还没有打开文件
- case Stopped://停止了--打开文件后就是此状态
- return 0;
- break;
- case Started://开始播放了
- return 1;
- break;
- case Paused://暂停了
- return 2;
- break;
- default:
- return -1;
- break;
- }
- }
- BOOL CSpsPlayer::Play()
- {
- CMyAutoLock lock(&m_csCrit);
- if (m_state != Paused && m_state != Stopped)
- {
- return FALSE;
- }
- PROPVARIANT varStart;
- PropVariantInit(&varStart);
- HRESULT hr = m_pSession->Start(&GUID_NULL, &varStart);
- PropVariantClear(&varStart);
- if (SUCCEEDED(hr))
- {
- // Note: Start is an asynchronous operation. However, we
- // can treat our state as being already started. If Start
- // fails later, we'll get an MESessionStarted event with
- // an error code, and we will update our state then.
- m_state = Started;
- return TRUE;
- }
- return FALSE;
- }
- BOOL CSpsPlayer::Pause()
- {
- CMyAutoLock lock(&m_csCrit);
- if (m_state != Started)
- {
- return FALSE;
- }
- HRESULT hr = m_pSession->Pause();
- if (SUCCEEDED(hr))
- {
- m_state = Paused;
- return TRUE;
- }
- return FALSE;
- }
- BOOL CSpsPlayer::Stop()
- {
- CMyAutoLock lock(&m_csCrit);
- if (m_state != Started && m_state != Paused)
- {
- return FALSE;
- }
- HRESULT hr = m_pSession->Stop();
- if (SUCCEEDED(hr))
- {
- m_state = Stopped;
- return TRUE;
- }
- return FALSE;
- }
- LONGLONG CSpsPlayer::GetTimeLen()
- {
- CMyAutoLock lock(&m_csCrit);
- return m_llTimeLen;
- }
- LONGLONG CSpsPlayer::GetCurrentPos()
- {
- CMyAutoLock lock(&m_csCrit);
- IMFPresentationClock* pPresentationClock = GetPresentationClock();
- if (!pPresentationClock)
- return 0;
- MFTIME pos = 0;
- HRESULT hr = pPresentationClock->GetTime(&pos);
- SAFE_RELEASE(pPresentationClock);
- if (FAILED(hr))
- return 0;
- return pos;
- }
- BOOL CSpsPlayer::Move(LONGLONG pos)
- {
- CMyAutoLock lock(&m_csCrit);
- if (!m_pSession)
- return FALSE;
- PROPVARIANT varStart;
- varStart.vt = VT_I8;
- varStart.hVal.QuadPart = pos;
- HRESULT hr = m_pSession->Start(NULL, &varStart);
- if (FAILED(hr))
- return FALSE;
- return TRUE;
- }
- BOOL CSpsPlayer::GetAudioIsOpenedOrClosed()
- {
- CMyAutoLock lock(&m_csCrit);
- if (!m_pSession)
- {
- return FALSE;
- }
- IMFSimpleAudioVolume* pa = GetSimpleAudioVolume();
- if(pa)
- {
- BOOL bMute = FALSE;
- HRESULT hr = pa->GetMute(&bMute);
- if (FAILED(hr))
- return FALSE;
- return bMute;
- }
- return FALSE;
- }
- BOOL CSpsPlayer::OpenOrCloseAudio(BOOL bOpen)
- {
- CMyAutoLock lock(&m_csCrit);
- if (!m_pSession)
- {
- return FALSE;
- }
- IMFSimpleAudioVolume* pa = GetSimpleAudioVolume();
- if(pa)
- {
- HRESULT hr;
- if (bOpen)
- {
- hr = pa->SetMute(FALSE);
- if (FAILED(hr))
- return FALSE;
- }
- else
- {
- hr = pa->SetMute(TRUE);
- if (FAILED(hr))
- return FALSE;
- }
- }
- return TRUE;
- }
- long CSpsPlayer::GetAudioVolumn()
- {
- CMyAutoLock lock(&m_csCrit);
- if (!m_pSession)
- {
- return 0;
- }
- IMFSimpleAudioVolume* pa = GetSimpleAudioVolume();
- if(pa)
- {
- HRESULT hr;
- float f = 0.0f;
- hr = pa->GetMasterVolume(&f);
- if (FAILED(hr))
- return 0;
- f = (f < 0.0f ? 0.0f : (f > 1.0f ? 1.0f : f));
- return (long)(f * 100.0f);
- }
- return 0;
- }
- BOOL CSpsPlayer::SetAudioVolumn(long ll)
- {
- CMyAutoLock lock(&m_csCrit);
- if (!m_pSession)
- {
- return FALSE;
- }
- IMFSimpleAudioVolume* pa = GetSimpleAudioVolume();
- if(pa)
- {
- HRESULT hr;
- ll = (ll < 0 ? 0 : (ll > 100 ? 100 : ll));
- float f = ((float)ll / 100.0f);
- f = (f < 0.0f ? 0.0f : (f > 1.0f ? 1.0f : f));
- hr = pa->SetMasterVolume(f);
- if (FAILED(hr))
- return FALSE;
- return TRUE;
- }
- return FALSE;
- }
- void CSpsPlayer::AdjustWindowPosition()
- {
- CMyAutoLock lock(&m_csCrit);
- IMFVideoDisplayControl* pVideoDisplayControl = GetVideoDisplayControl();
- if (pVideoDisplayControl)
- {
- RECT rcDest;
- GetWindowRect(m_hWndVideo, &rcDest);
- POINT pt;
- pt.x = rcDest.left;
- pt.y = rcDest.top;
- ScreenToClient(m_hWndVideo, &pt);
- rcDest.left = pt.x;
- rcDest.top = pt.y;
- pt.x = rcDest.right;
- pt.y = rcDest.bottom;
- ScreenToClient(m_hWndVideo, &pt);
- rcDest.right = pt.x;
- rcDest.bottom = pt.y;
- pVideoDisplayControl->SetVideoPosition(0, &rcDest);
- }
- }
- void CSpsPlayer::RepaitVideo()
- {
- CMyAutoLock lock(&m_csCrit);
- IMFVideoDisplayControl* pVideoDisplayControl = GetVideoDisplayControl();
- if (pVideoDisplayControl)
- pVideoDisplayControl->RepaintVideo();
- }
- BOOL CSpsPlayer::AddBranchToTopology( IMFTopology *pTopology, IMFMediaSource *pSource, IMFPresentationDescriptor *pPD, DWORD iStream)
- {
- IMFStreamDescriptor *pSD = NULL;
- IMFTopologyNode *pSourceNode = NULL;
- IMFTopologyNode *pOutputNode = NULL;
- BOOL fSelected = FALSE;
- //获取流描述符
- HRESULT hr = pPD->GetStreamDescriptorByIndex(iStream, &fSelected, &pSD);
- if (FAILED(hr))
- {
- return FALSE;
- }
- if (fSelected)
- {
- // Create the media sink activation object.
- IMFMediaTypeHandler *pHandler = NULL;
- IMFActivate *pActivate = NULL;
- //获取流的IMFMeidaTypeHandle
- HRESULT hr = pSD->GetMediaTypeHandler(&pHandler);
- if (FAILED(hr))
- {
- SAFE_RELEASE(pSD);
- return FALSE;
- }
- //获取流的主类型
- GUID guidMajorType;
- hr = pHandler->GetMajorType(&guidMajorType);
- if (FAILED(hr))
- {
- SAFE_RELEASE(pHandler);
- SAFE_RELEASE(pSD);
- return FALSE;
- }
- SAFE_RELEASE(pHandler);
- // 根据流的主类型为Render创建IMFActivate对象
- if (MFMediaType_Audio == guidMajorType)
- {
- hr = MFCreateAudioRendererActivate(&pActivate);
- if (FAILED(hr))
- {
- SAFE_RELEASE(pSD);
- return FALSE;
- }
- }
- else if (MFMediaType_Video == guidMajorType)
- {
- hr = MFCreateVideoRendererActivate(m_hWndVideo, &pActivate);
- if (FAILED(hr))
- {
- SAFE_RELEASE(pSD);
- return FALSE;
- }
- }
- //创建源节点
- hr = MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE, &pSourceNode);
- if (FAILED(hr))
- {
- SAFE_RELEASE(pActivate);
- SAFE_RELEASE(pSD);
- return FALSE;
- }
- //设置源节点的源属性
- hr = pSourceNode->SetUnknown(MF_TOPONODE_SOURCE, pSource);
- if (FAILED(hr))
- {
- SAFE_RELEASE(pSourceNode);
- SAFE_RELEASE(pActivate);
- SAFE_RELEASE(pSD);
- return FALSE;
- }
- //设置源节点的Presentation描述符
- hr = pSourceNode->SetUnknown(MF_TOPONODE_PRESENTATION_DESCRIPTOR, pPD);
- if (FAILED(hr))
- {
- SAFE_RELEASE(pSourceNode);
- SAFE_RELEASE(pActivate);
- SAFE_RELEASE(pSD);
- return FALSE;
- }
- //设置源节点的流的描述符
- hr = pSourceNode->SetUnknown(MF_TOPONODE_STREAM_DESCRIPTOR, pSD);
- if (FAILED(hr))
- {
- SAFE_RELEASE(pSourceNode);
- SAFE_RELEASE(pActivate);
- SAFE_RELEASE(pSD);
- return FALSE;
- }
- //添加源节点到topology.
- hr = pTopology->AddNode(pSourceNode);
- if (FAILED(hr))
- {
- SAFE_RELEASE(pSourceNode);
- SAFE_RELEASE(pActivate);
- SAFE_RELEASE(pSD);
- return FALSE;
- }
- //创建输出节点
- hr = MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, &pOutputNode);
- if (FAILED(hr))
- {
- SAFE_RELEASE(pSourceNode);
- SAFE_RELEASE(pActivate);
- SAFE_RELEASE(pSD);
- return FALSE;
- }
- //设置输出节点的指针
- hr = pOutputNode->SetObject(pActivate);
- if (FAILED(hr))
- {
- SAFE_RELEASE(pOutputNode);
- SAFE_RELEASE(pSourceNode);
- SAFE_RELEASE(pActivate);
- SAFE_RELEASE(pSD);
- return FALSE;
- }
- SAFE_RELEASE(pActivate);
- //设置输出节点所在流的id
- hr = pOutputNode->SetUINT32(MF_TOPONODE_STREAMID, 0);
- if (FAILED(hr))
- {
- SAFE_RELEASE(pOutputNode);
- SAFE_RELEASE(pSourceNode);
- SAFE_RELEASE(pSD);
- return FALSE;
- }
- hr = pOutputNode->SetUINT32(MF_TOPONODE_NOSHUTDOWN_ON_REMOVE, FALSE);
- if (FAILED(hr))
- {
- SAFE_RELEASE(pOutputNode);
- SAFE_RELEASE(pSourceNode);
- SAFE_RELEASE(pSD);
- return FALSE;
- }
- //添加输出节点到topology.
- hr = pTopology->AddNode(pOutputNode);
- if (FAILED(hr))
- {
- SAFE_RELEASE(pOutputNode);
- SAFE_RELEASE(pSourceNode);
- SAFE_RELEASE(pSD);
- return FALSE;
- }
- hr = pSourceNode->ConnectOutput(0, pOutputNode, 0);
- if (FAILED(hr))
- {
- SAFE_RELEASE(pOutputNode);
- SAFE_RELEASE(pSourceNode);
- SAFE_RELEASE(pSD);
- return FALSE;
- }
- }
- SAFE_RELEASE(pOutputNode);
- SAFE_RELEASE(pSourceNode);
- SAFE_RELEASE(pSD);
- return TRUE;
- }
- HRESULT CSpsPlayer::Invoke(IMFAsyncResult *pResult)
- {
- MediaEventType meType = MEUnknown; // Event type
- IMFMediaEvent *pEvent = NULL;
- m_csCrit.lock();
- // Get the event from the event queue.
- HRESULT hr = m_pSession->EndGetEvent(pResult, &pEvent);
- if (FAILED(hr))
- {
- m_csCrit.unlock();
- return S_OK;
- }
- // Get the event type.
- hr = pEvent->GetType(&meType);
- if (FAILED(hr))
- {
- SAFE_RELEASE(pEvent);
- m_csCrit.unlock();
- return S_OK;
- }
- if (meType == MEEndOfPresentation)
- {
- SAFE_RELEASE(pEvent);
- m_csCrit.unlock();
- Stop();
- return S_OK;
- }
- else
- {
- SAFE_RELEASE(pEvent);
- // For all other events, get the next event in the queue.
- hr = m_pSession->BeginGetEvent(this, NULL);
- if (FAILED(hr))
- {
- //error
- }
- }
- m_csCrit.unlock();
- return S_OK;
- }
- IMFGetService* CSpsPlayer::GetMFGetService()
- {
- if (!m_pSession)
- return NULL;
- IMFGetService* pGetService = NULL;
- HRESULT hr = m_pSession->QueryInterface(IID_IMFGetService, (void **)&pGetService);
- if(FAILED(hr))
- return NULL;
- return pGetService;
- }
- IMFSimpleAudioVolume* CSpsPlayer::GetSimpleAudioVolume()
- {
- if (!m_pSession)
- return NULL;
- IMFGetService* pGetService = GetMFGetService();
- if(!pGetService)
- return NULL;
- IMFSimpleAudioVolume* pa = NULL;
- HRESULT hr = pGetService->GetService(MR_POLICY_VOLUME_SERVICE, IID_PPV_ARGS(&pa));
- SAFE_RELEASE(pGetService);
- if(FAILED(hr))
- return NULL;
- return pa;
- }
- IMFPresentationClock* CSpsPlayer::GetPresentationClock()
- {
- if (!m_pSession)
- return NULL;
- IMFClock* pClock = NULL;
- HRESULT hr = m_pSession->GetClock(&pClock);
- if(FAILED(hr))
- return NULL;
- IMFPresentationClock* pPresentationClock = NULL;
- hr = pClock->QueryInterface(IID_PPV_ARGS(&pPresentationClock));
- SAFE_RELEASE(pClock);
- if(FAILED(hr))
- return NULL;
- return pPresentationClock;
- }
- IMFVideoDisplayControl* CSpsPlayer::GetVideoDisplayControl()
- {
- if (!m_pSession)
- return NULL;
- IMFVideoDisplayControl* pVideoDisplay = NULL;
- HRESULT hr = MFGetService(m_pSession, MY_MR_VIDEO_RENDER_SERVICE, IID_PPV_ARGS(&pVideoDisplay));
- if(FAILED(hr))
- return NULL;
- return pVideoDisplay;