Windows-driver-samples/avstream/avscamera/DMFT/mftpeventgenerator.cpp

235 строки
4.2 KiB
C++

//*@@@+++@@@@******************************************************************
//
// Microsoft Windows Media Foundation
// Copyright (C) Microsoft Corporation. All rights reserved.
//
//*@@@---@@@@******************************************************************
//
#include "stdafx.h"
#include "common.h"
#include "mftpeventgenerator.h"
#ifdef MF_WPP
#include "mftpeventgenerator.tmh" //--REF_ANALYZER_DONT_REMOVE--
#endif
CMediaEventGenerator::CMediaEventGenerator () :
m_nRefCount(0),
m_pQueue(NULL),
m_bShutdown(FALSE)
{
//Call this explicit...
InitMediaEventGenerator();
}
STDMETHODIMP CMediaEventGenerator::InitMediaEventGenerator(
void
)
{
return MFCreateEventQueue(&m_pQueue);
}
STDMETHODIMP_(ULONG) CMediaEventGenerator::AddRef(
void
)
{
return InterlockedIncrement(&m_nRefCount);
}
STDMETHODIMP_(ULONG) CMediaEventGenerator::Release(
void
)
{
ULONG uCount = InterlockedDecrement(&m_nRefCount);
if (uCount == 0)
{
delete this;
}
return uCount;
}
STDMETHODIMP CMediaEventGenerator::QueryInterface(
_In_ REFIID iid,
_COM_Outptr_ void** ppv)
{
HRESULT hr = S_OK;
*ppv = NULL;
if (iid == __uuidof(IUnknown) || iid == __uuidof(IMFMediaEventGenerator))
{
*ppv = static_cast<IMFMediaEventGenerator*>(this);
AddRef();
}
else
{
hr = E_NOINTERFACE;
}
return hr;
}
//
// IMediaEventGenerator methods
//
STDMETHODIMP CMediaEventGenerator::BeginGetEvent(
_In_ IMFAsyncCallback* pCallback,
_In_ IUnknown* pState
)
{
HRESULT hr = S_OK;
m_critSec.Lock();
hr = CheckShutdown();
if (SUCCEEDED(hr))
{
hr = m_pQueue->BeginGetEvent(pCallback, pState);
}
m_critSec.Unlock();
return hr;
}
STDMETHODIMP CMediaEventGenerator::EndGetEvent(
_In_ IMFAsyncResult* pResult,
_Outptr_result_maybenull_ IMFMediaEvent** ppEvent
)
{
HRESULT hr = S_OK;
m_critSec.Lock();
hr = CheckShutdown();
if (SUCCEEDED(hr))
{
hr = m_pQueue->EndGetEvent(pResult, ppEvent);
}
m_critSec.Unlock();
return hr;
}
STDMETHODIMP CMediaEventGenerator::GetEvent(
_In_ DWORD dwFlags,
_Outptr_result_maybenull_ IMFMediaEvent** ppEvent
)
{
//
// Because GetEvent can block indefinitely, it requires
// a slightly different locking strategy.
//
HRESULT hr = S_OK;
IMFMediaEventQueue *pQueue = NULL;
m_critSec.Lock();
hr = CheckShutdown();
//
// Store the pointer in a local variable, so that another thread
// does not release it after we leave the critical section.
//
if (SUCCEEDED(hr))
{
pQueue = m_pQueue;
}
m_critSec.Unlock();
if (SUCCEEDED(hr))
{
hr = pQueue->GetEvent(dwFlags, ppEvent);
}
return hr;
}
STDMETHODIMP CMediaEventGenerator::QueueEvent(
_In_ MediaEventType met,
_In_ REFGUID extendedType,
_In_ HRESULT hrStatus,
_In_opt_ const PROPVARIANT* pvValue
)
{
HRESULT hr = S_OK;
m_critSec.Lock();
hr = CheckShutdown();
if (SUCCEEDED(hr))
{
hr = m_pQueue->QueueEventParamVar(
met,
extendedType,
hrStatus,
pvValue
);
}
m_critSec.Unlock();
return hr;
}
STDMETHODIMP CMediaEventGenerator::ShutdownEventGenerator(
void
)
{
HRESULT hr = S_OK;
m_critSec.Lock();
hr = CheckShutdown();
if (SUCCEEDED(hr))
{
if (m_pQueue)
{
hr = m_pQueue->Shutdown();
}
SAFE_RELEASE(m_pQueue);
m_bShutdown = TRUE;
}
m_critSec.Unlock();
return hr;
}
STDMETHODIMP CMediaEventGenerator::QueueEvent(
_In_ IMFMediaEvent* pEvent
)
{
HRESULT hr = S_OK;
m_critSec.Lock();
hr = CheckShutdown();
if (SUCCEEDED(hr))
{
if (m_pQueue)
{
hr = m_pQueue->QueueEvent(pEvent);
}
}
m_critSec.Unlock();
return hr;
}
CMediaEventGenerator::~CMediaEventGenerator (
void
)
{
ShutdownEventGenerator();
}